对于上一篇中的简单工厂模式,它利用一个【工厂类】来有选择型的实例化指定的对象(要利用加法类时,传入参数“加法”之后工厂类就会去实例化OperateAdd类,并返回该实例),而对于工厂方法模式来说,他为每个操作类都创建一个工厂类,调用工厂类再来实例化指定对象!

首先来创建一个接口,来统一各个工厂类的行为
interface IFactory
{
  Operation CreateOperation(); //返回值类型为所有操作类的父类
}

工厂方法模式_工厂方法模式工厂方法模式_工厂方法模式_02
public AddFactory:IFactory
{
  public Operation CreateOperation()
  {
    return new OperationAdd();
  }
}
AddFactory-加法工厂类
工厂方法模式_工厂方法模式工厂方法模式_工厂方法模式_02
public SubFactory:IFactory
{
  public Operation CreateOperation()
  {
    return new OperationSub();
  }
}
SubFactory-减法工厂类
工厂方法模式_工厂方法模式工厂方法模式_工厂方法模式_02
public MulFactory:IFactory
{
  public Operation CreateOperation()
  {
    return new OperationMul();
  }
}
MulFactory-乘法工厂类

  上述这些工厂类都返回给自对应的操作类的实例,当想要利用加法操作时,只需要调用工厂类中的CreateOperation方法即可,那么对于到底该调用那个工厂类的逻辑判断,就需要自己来写了,这一点工厂方法模式和简单工厂模式是不同的!

工厂方法模式_工厂方法模式工厂方法模式_工厂方法模式_02
  //定义一个父类,来统一计算操作。
  public class Operate
    {
        private int _numberA;
        private int _numberB;

        public int numberA
        {
            set { _numberA = value; }
            get { return _numberA; }
        }
        public int numberB
        {
            set { _numberB = value; }
            get { return _numberB; }
        }
     //其实可以将此类设置为抽象类,此方法设置为抽象方法,因为具体的实现都是在其派生类中进行的!
        public virtual int ObtainResult()
        {return 0;
        }
    }
  //加法类
    public class OperationAdd:Operate
    {
        public override int ObtainResult()
        {
            return base.numberA + base.numberB;
        }
    }
  //减法类
    public class OperationSub : Operate
    {
        public override int ObtainResult()
        {
            return base.numberA - base.numberB;
        }
    }
操作类

 

  1.看起来工厂方法模式对于简单工厂模式来说也米有优势,算是反倒麻烦了,因为对到底应该调用那一个工厂类的逻辑判断抛了出来,需要在客户端代码中自己来做判定。

  2.工厂方法模式遵循了 开放-封闭原则,对于工厂方法模式来说,如果要对其进行扩展(添加除法操作),需要添加了一个继承自Operate类的除法操作类,再添加一个实现IFactory接口的除法工厂类即可,而如果对简单工厂模式进行扩展的话,不仅需要增加操作类,还需要去对工厂类进行逻辑的修改,这么一来就违背了开放-封闭原则。其实,两者本质的差别是因为在工厂方法模式中判断到底调用那一个工厂类的操作抛给了客户端代码来实现,所以在组件的范围内就不需要修改,只扩展即可。

 

 

工厂方法模式_工厂方法模式_09
作者:武沛齐
本文版权归作者和博客共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。