工厂方法模式(Factory Method pattern)

简介

“工厂方法模式(Factory Method Pattern)又称为工厂模式,也叫虚拟构造器(Virtual Constructor)模式或者多态工厂(Polymorphic Factory)模式,它属于类创建型模式。在工厂方法模式中,工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类。

与简单工厂模式的对比

以计算器为例

简单工厂模式

  1. public class OperationFactory
  2. {
  3. public static operation createOperate(string operate)
  4. {
  5. Operation oper = null;
  6. switch (operate)
  7. {
  8. case "+":
  9. oper = new OperationAdd();
  10. break;
  11. case "-":
  12. oper = new OperationSub();
  13. break;
  14. case "*":
  15. oper = new OperationMul();
  16. break;
  17. case "/":
  18. oper = new OperationDiv();
  19. break;
  20. }
  21. return oper;
  22. }
  23. }

客户端代码

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

工厂方法模式

  1. interface IFactory
  2. {
  3. Operation CreateOperation();
  4. }

然后加减乘除各建一个具体工厂去实现这个接口。

  1. class addFactory: IFactory
  2. {
  3. public Operation CreateOperation()
  4. {
  5. return new OperationAdd();
  6. }
  7. }
  8. class subFactory: IFactory
  9. {
  10. public Operation CreateOperation()
  11. {
  12. return new OperationSub();
  13. }
  14. }
  15. class mulFactory: IFactory
  16. {
  17. public Operation CreateOperation()
  18. {
  19. return new OperationMul();
  20. }
  21. }
  22. class divFactory: IFactory
  23. {
  24. public Operation CreateOperation()
  25. {
  26. return new OperationDiv();
  27. }
  28. }

客户端的实现是这样的。

  1. IFactory operFactory = new addFactory();
  2. operation oper = operationFactory.CreateOperation();
  3. oper.NumberA = 1;
  4. oper.NumberB = 2;
  5. double result = oper.GetResult();

简单工厂模式的最大优点在于工厂类中包涵了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体相关产品的依赖。就像你的计算器,让客户端不用管该用哪个类的实例,只需要把’+’给工厂,工厂自动就给出了相应的实例,客户端只要去做运算就可以了,不同的实例会实现不同的运算。但是问题也就在这里,如你所说,如果要加一个’求M数的N次方’的功能,我们是一定需要给运算工厂类的方法里加’case’的分支条件的,修改原来的类并不是好方法,这就等于说,我们不但对扩展开放了,对修改也开放了,这样违背了开放封闭原则。

工厂方法模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
其实你仔细观察会发现,工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来运行,你想要加功能,本来是修改工厂类的,而现在修改客户端。