1. 简单工厂的实现

B: 这个和简单工厂有什么区别,感觉还不如简单工厂方便,为什么要用这个模式,到底这个模式的精髓在哪里?

简单工厂模式结构图:
图1
工厂类的代码:

class OperationFactory
{
    public static Operation createOperate(string operate)
    {
        Operation oper = null;
        switch (operate)
        {
            case "+":
                {
                    oper = new OperationAdd();
                    break;
                }
            case "-":
                {
                    oper = new OperationSub();
                    break;
                }
            case "*":
                {
                    oper = new OperationMul();
                    break;
                }
            case "/":
                {
                    oper = new OperationDiv();
                    break;
                }
        }
    }
}

客户端:

Operation oper;
oper = OperationFactory.createOperate("+");
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();

2. 工厂方法模式实现

工厂方法结构图:
图2

class Operation
{
    private double _numberA = 0;
    private double _numberB = 0;

    public double NumberA
    {
        get { return _numberA; }
        set { _numberA = value; }
    }

    public double NumberB
    {
        get { return _numberB; }
        set { _numberB = value; }
    }

    /// <summary>
    /// 得到运算结果
    /// </summary>
    /// <returns></returns>
    public virtual double GetResult()
    {
        double result = 0;
        return result;
    }
}

/// <summary>
/// 加法类
/// </summary>
class OperationAdd : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA + NumberB;
        return result;
    }
}

/// <summary>
/// 减法类
/// </summary>
class OperationSub : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA - NumberB;
        return result;
    }
}
/// <summary>
/// 乘法类
/// </summary>
class OperationMul : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA * NumberB;
        return result;
    }
}
/// <summary>
/// 除法类
/// </summary>
class OperationDiv : Operation
{
    public override double GetResult()
    {
        double result = 0;
        if (NumberB == 0)
            throw new Exception("除数不能为0。");
        result = NumberA / NumberB;
        return result;
    }
}

/// <summary>
/// 工厂方法
/// </summary>
interface IFactory
{
    Operation CreateOperation();
}

/// <summary>
/// 专门负责生产“+”的工厂
/// </summary>
class AddFactory : IFactory
{
    public Operation CreateOperation()
    {
        return new OperationAdd();
    }
}

/// <summary>
/// 专门负责生产“-”的工厂
/// </summary>
class SubFactory : IFactory
{
    public Operation CreateOperation()
    {
        return new OperationSub();
    }
}

/// <summary>
/// 专门负责生产“*”的工厂
/// </summary>
class MulFactory : IFactory
{
    public Operation CreateOperation()
    {
        return new OperationMul();
    }
}

/// <summary>
/// 专门负责生产“/”的工厂
/// </summary>
class DivFactory : IFactory
{
    public Operation CreateOperation()
    {
        return new OperationDiv();
    }
}

客服端:

class Program
{
    static void Main(string[] args)
    {
        IFactory operFactory = new AddFactory();
        Operation oper = operFactory.CreateOperation();
        oper.NumberA = 1;
        oper.NumberB = 2;
        double result=oper.GetResult();

        Console.WriteLine(result);

        Console.Read();
    }
}

3. 简单工厂vs.工厂方法

B: 增加其他运算,例如M数的N次方,这些功能的增加,在简单工厂里,我是先去加'求M数的N次方'功能类,然后去更改工厂方法,当中加入'Case'语句来做判断,现在用来工厂方法,加功能类没有问题,再加相关的工厂类,这也没问题,但要我再去改客服端,这不等于不但没有减低难度,反而增加了很多类和方法,把复杂性提高了?
A: 简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客服端的选择条件动态的实例化相关的类,对于客服端来说,去除了与具体产品的依赖。但问题也就在这里,如你所说,增加运算类,我们是一定需要给运算工厂类的方法里加'Case'的分支条件,修改原有的类?这等于说,我们不但对于扩展开放,对于修改也开放,这就背叛了开放-封闭原则。工厂方法就是为了解决这个。

定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。

工厂方法模式结构图:
图3
A:既然这个工厂类与分支耦合,那么我就对它下手,根据依赖倒转原则,我们把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。然后,所有的要生产具体产品类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生成对象的工厂,于是增加运算类时,就不需要更改原有的工厂类了,只需要增加此功能的运算类和相应的工厂类就可以了。
图4
A: 工厂方法模式实现时,客服端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑移到了客服端代码来进行。你想要加功能,本来是改工厂类,而现在是修改客服端。

4. 雷锋工厂

B: 老人不需要知道是谁来做好事,他只需知道是学雷锋的人来帮忙就可以了。

class Program
{
    static void Main(string[] args)
    {

        //
        //基本方式:薛磊风代表大学生学习雷锋
        LeiFeng xueleifeng = new Undergraduate();

        xueleifeng.BuyRice();
        xueleifeng.Sweep();
        xueleifeng.Wash();


        LeiFeng student1 = new Undergraduate();
        student1.BuyRice();
        LeiFeng student2 = new Undergraduate();
        student2.Sweep();
        LeiFeng student3 = new Undergraduate();
        student3.Wash();



        //简单工厂模式
        LeiFeng studentA = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
        studentA.BuyRice();
        LeiFeng studentB = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
        studentB.Sweep();
        LeiFeng studentC = SimpleFactory.CreateLeiFeng("学雷锋的大学生");
        studentC.Wash();


        //工厂方法模式
        IFactory factory = new UndergraduateFactory();
        LeiFeng student = factory.CreateLeiFeng();

        student.BuyRice();
        student.Sweep();
        student.Wash();

        Console.Read();
    }
}

//雷锋
class LeiFeng
{
    public void Sweep()
    {
        Console.WriteLine("扫地");
    }

    public void Wash()
    {
        Console.WriteLine("洗衣");
    }

    public void BuyRice()
    {
        Console.WriteLine("买米");
    }
}

//学雷锋的大学生
class Undergraduate : LeiFeng
{ }

//社区志愿者
class Volunteer : LeiFeng
{ }

//简单雷锋工厂
class SimpleFactory
{
    public static LeiFeng CreateLeiFeng(string type)
    {
        LeiFeng result = null;
        switch (type)
        {
            case "学雷锋的大学生":
                result = new Undergraduate();
                break;
            case "社区志愿者":
                result = new Volunteer();
                break;

        }
        return result;
    }
}

//雷锋工厂
interface IFactory
{
    LeiFeng CreateLeiFeng();
}

//学雷锋的大学生工厂
class UndergraduateFactory : IFactory
{
    public LeiFeng CreateLeiFeng()
    {
        return new Undergraduate();
    }
}

//社区志愿者工厂
class VolunteerFactory : IFactory
{
    public LeiFeng CreateLeiFeng()  
    {
        return new Volunteer();
    }
}

A: 简单工厂实例化是要3遍,而工厂模式只需一次。
B: 我觉得工厂方法克服了简单工厂违背开放-封闭原则,又保持了封装对象创建过程的优点。
A: 由于使用了多态性,工厂方法模式保持了简单工厂的优点,而且克服了它的缺点。但是缺点是由于每加一个产品,就需要加一个产品工厂的类,增加了额外的开发量。
A: 利用'反射'可以解决避免分支判断的问题。


yuanoung
10 声望1 粉丝

« 上一篇
代理模式
下一篇 »
原型模式

引用和评论

0 条评论