简单工厂模式 与 工厂方法模式

摘自《大话设计模式》(程杰 著)

区别

简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类。
对于客户端来说,去除了与具体产品的依赖。

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

简单工厂模式

面向对象的分析设计编程思想:通过封装、继承、多态把程序的耦合度降低。
让业务逻辑与界面逻辑分开,让它们之间的耦合度下降,容易维护或扩展。​

简单工厂模式可以方便地解决对象的创建问题。但每次维护和拓展功能都需要改动工厂,以致代码需要重新编译部署。

计算器控制台程序,要求输入两个数和运算符号,得到结果。

如果需要更改某一运算,我们只需要改对应的OperationXXX子类。
如果需要增加各种复杂运算,比如平方根,立方根,自然对数,正弦余弦等,只要增加相应的运算子类,并在运算类工厂switch中增加分支。
如果需要改界面,不会影响到运算。

image

Operation.cs

把加减乘除都写成运算类的子类,继承它后,重写GetResult()方法。
这样如果要修改任何一个算法,就不需要提供其他算法的代码。

public 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; }
    }
    public virtual double GetResult()
    {
        double result = 0;
        return result;
    }
}

class OperationAdd: Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA + NumberB;
        return result;
    }
}

class OperationSub : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA - NumberB;
        return result;
    }
}

class OperationMul : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA * NumberB;
        return result;
    }
}

class OperationDiv : Operation
{
    public override double GetResult()
    {
        double result = 0;
        if (NumberB == 0)
            throw new Exception("除数不能为0");
        result = NumberA / NumberB;
        return result;
    }
}

OperationFactory.cs

用一个单独的类来做这个创造实例的过程。
只需要输入运算符号,工厂就实例化出合适的对象,通过多态,返回父类的方式实现了计算器的结果。

public 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;
        }

        return oper;
    }
}

Program.cs

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

工厂方法模式

image

根据依赖倒转原则,我们把工厂类抽象出一个接口,这个接口只有一个方法,就是创建抽象产品的工厂方法。
然后,所有的要生产具体类的工厂,就去实现这个接口,这样,一个简单工厂模式的工厂类,变成了一个工厂抽象接口和多个具体生成对象的工厂,
于是我们要增加“求M数的N次方”的功能时,就不需要更改原有的工厂类了,只需要增加此功能的运算类和相应的工厂类就可以了。
这样整个工厂和产品体系其实都没有修改的变化,而只是扩展的变化,这就完全符合了开放-封闭原则的精神。

image

Operation.cs

public 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; }
    }
    public virtual double GetResult()
    {
        double result = 0;
        return result;
    }
}

OperationAdd.cs

class OperationAdd : Operation
{
    public override double GetResult()
    {
        double result = 0;
        result = NumberA + NumberB;
        return result;
    }
}

其他几个类似
image

IFactory.cs

interface IFactory
{
    Operation CreateOperation();
}

AddFactory.cs

class AddFactory: IFactory
{
    public Operation CreateOperation()
    {
        return new OperationAdd();
    }
}

其他几个类似
image

Program.cs

IFactory operFactory = new AddFactory();
Operation oper = operFactory.CreateOperation();
oper.NumberA = 1;
oper.NumberB = 2;
double result = oper.GetResult();
posted @ 2025-12-08 10:58  苦涩如影相随固  阅读(3)  评论(0)    收藏  举报