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

——DP

UML类图

设计模式——工厂方法(Factory Method)

模式说明

抽象业务基类

实际业务类的公共基类,也是工厂要创建的所有对象的父类,这部分同简单工厂。在这里是一个计算基类,定义了两个参数和一个抽象的计算方法:

    /// <summary>
    /// 计算基类
    /// </summary>
    abstract class Operation
    {
        public double NumberA { get; set; }
        public double NumberB { get; set; }

        public abstract double GetResult();
    }

有了抽象的业务基类,那么要根据实现业务来实现具体的业务子类。这里是具体计算方法的各种实现:

    /// <summary>
    /// 加法运算
    /// </summary>
    class OperationAdd:Operation
    {
        public override double GetResult()
        {
            return NumberA + NumberB;
        }
    }
    /// <summary>
    /// 减法运算
    /// </summary>
    class OperationSub : Operation
    {
        public override double GetResult()
        {
            return NumberA - NumberB;
        }
    }

工厂类

由于简单工厂,在工厂类中存在大量的if...else或switch...case判断语句,在添加新业务类的时候,还是需要修改工厂类(添加新的判断语句)才能实现,这就违背了一条重要的设计原则——开闭原则。所以工厂方法模式中,将这些判断逻辑抽象出来,抽象成一个创建业务类的接口(即定义中的“定义一个用于创建对象的接口”),然后由具体的工厂子类来创建各自的业务对象。

计算工厂类抽象出的统一接口:

    /// <summary>
    /// 计算工厂类接口
    /// </summary>
    interface IOperationFactory
    {
        Operation CreateOperation();
    }

具体的计算工厂类(创建各自的业务对象):

    /// <summary>
    /// 加法运算工厂
    /// </summary>
    class OperationAddFactory:IOperationFactory
    {
        public Operation CreateOperation()
        {
            return new OperationAdd();
        }
    }
    /// <summary>
    /// 减法运算工厂
    /// </summary>
    class OperationSubFactory:IOperationFactory
    {
        public Operation CreateOperation()
        {
            return new OperationSub();
        }
    }

这样设计后,客户端只要根据需要,实例化一个具体的计算工厂,然后用工厂生成业务对象,就可以进行计算了:

            IOperationFactory factory = new OperationAddFactory();
            Operation op = factory.CreateOperation();

            op.NumberA = 2;
            op.NumberB = 5;
            double result = op.GetResult();

总结

工厂方法模式是对简单工厂模式中的工厂类,进行了面向对象的重构。使其在面对变化时,不需要修改工厂类里的判断逻辑,而是通过扩展(添加新的业务类和工厂类)来完成,这就使得工厂类的设计也完全符合开闭原则了。

参考

  1. 程杰老师  《大话设计模式》

相关文章: