码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式(二)工厂模式:2-工厂方法模式

时间:2017-09-17 00:21:56      阅读:229      评论:0      收藏:0      [点我收藏+]

标签:技术   方案   变化   简单工厂   win   最大的   测试   val   str   

模拟场景:

 

  继续沿用在简单工厂模式中讨论的,运算器相关的场景。

 

 

思想:

 

  考虑之前最初的设计,简单工厂模式中,最大的问题在于,面对新增的需要在工厂中创建的对象,对其的修改会违反开闭原则。

  工厂方法模式(Factory Method)对于这种问题的解决方案是:将生产运算器的工厂抽象出来(AbsOperationFactory),然后为原来每一个需要创建的对象(继承AbsOperation),都建立一个专门的工厂。这样一来,可以巧妙地利用多态的性质,完成代码的解耦。

  由此可见,工厂方法模式,是模板方法模式(Template Method)的一种典型应用,模板方法模式会在之后细讲。

  所以说,一个完整的工厂方法模式,除了客户端(Client)之外,还包括以下4个内容:

  • 抽象工厂(Abstract Factory)
  • 具体工厂(Concrete Factory)
  • 抽象产品(Abstract Product)
  • 具体产品(Concrete Product)

 

 

UML:

 

技术分享

 

 

分析:

 

  同样,以上是一个简化版的运算器 UML 类图。

  与简单工厂模式相同,也需要通过包结构来控制具体的 Operation 类只能由对应的工厂来创建。

  通过 Override 抽象类的方法,将工厂的返回对象,缩小为具体的对象,而非抽象父类。

 

 

代码:

  

技术分享
1 public abstract class AbsOperation {
2 
3     protected abstract double calc(double... vals);
4 
5 }
AbsOperation
技术分享
1 public abstract class AbsOperationFactory {
2 
3     protected abstract AbsOperation createOperation();
4 
5 }
AbsOperationFactory
技术分享
 1 public final class OperationAdd extends AbsOperation {
 2 
 3     OperationAdd() {
 4 
 5     }
 6 
 7     @Override
 8     public double calc(double... vals) {
 9         double sum = 0;
10         for (double num : vals) {
11             sum += num;
12         }
13         return sum;
14     }
15 
16 }
OperationAdd
技术分享
1 public final class OperationAddFactory extends AbsOperationFactory {
2 
3     public OperationAdd createOperation() {
4         return new OperationAdd();
5     }
6 
7 }
OperationAddFactory

 

 

Junit 即测试客户端调用:

 

技术分享
1     @Test
2     public void test() {
3         double[] vals1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
4         OperationAddFactory factory = new OperationAddFactory();
5         OperationAdd operator = factory.createOperation();
6         Assert.assertTrue(operator.calc(vals1) - 45 == 0);
7     }
JUnit

 

  工厂方法模式的最大优势在于:

  • 客户端可以自由决定调用的方式。
  • 产品的变化,不会影响客户端的调用。

 

 

总结:

 

  

  工厂方法模式面对产品的扩张,需要增加一个产品类和一个产品工厂类。这么做虽然解耦了,当时带来了更多的工作量。

 

  与简单工厂模式相比,工厂方法模式通过多态的运用,保证了开闭原则,但是这是通过多构造一个实例工厂的方式来完成的,这意味着近乎一倍的内存开销,所以在使用这种模式时,工厂内部负责创建的对象,不宜过多,否则得不偿失。

 

  与简单工厂模式的反射优化相比,工厂方法模式,几乎没有任何优势。工厂方法模式能做到的,简单工厂模式的反射优化,基本都能够做到,还少一倍的内存开销。要说优势,也就是通过 new 关键字正向创建对象,比反射的 newInstance() 方法速度更快,而且能在编译阶段发现错误。

 

  所以说,在我看来,工厂方法模式最大的意义,是为其扩展出去的抽象工厂模式(Abstract Factory)铺垫。而实际的应用,简单工厂模式的反射更具优势。

 

设计模式(二)工厂模式:2-工厂方法模式

标签:技术   方案   变化   简单工厂   win   最大的   测试   val   str   

原文地址:http://www.cnblogs.com/jing-an-feng-shao/p/7533443.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!