标签:技术 方案 变化 简单工厂 win 最大的 测试 val str
模拟场景:
继续沿用在简单工厂模式中讨论的,运算器相关的场景。
思想:
考虑之前最初的设计,简单工厂模式中,最大的问题在于,面对新增的需要在工厂中创建的对象,对其的修改会违反开闭原则。
工厂方法模式(Factory Method)对于这种问题的解决方案是:将生产运算器的工厂抽象出来(AbsOperationFactory),然后为原来每一个需要创建的对象(继承AbsOperation),都建立一个专门的工厂。这样一来,可以巧妙地利用多态的性质,完成代码的解耦。
由此可见,工厂方法模式,是模板方法模式(Template Method)的一种典型应用,模板方法模式会在之后细讲。
所以说,一个完整的工厂方法模式,除了客户端(Client)之外,还包括以下4个内容:
UML:
分析:
同样,以上是一个简化版的运算器 UML 类图。
与简单工厂模式相同,也需要通过包结构来控制具体的 Operation 类只能由对应的工厂来创建。
通过 Override 抽象类的方法,将工厂的返回对象,缩小为具体的对象,而非抽象父类。
代码:
1 public abstract class AbsOperation { 2 3 protected abstract double calc(double... vals); 4 5 }
1 public abstract class AbsOperationFactory { 2 3 protected abstract AbsOperation createOperation(); 4 5 }
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 }
1 public final class OperationAddFactory extends AbsOperationFactory { 2 3 public OperationAdd createOperation() { 4 return new OperationAdd(); 5 } 6 7 }
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 }
工厂方法模式的最大优势在于:
总结:
工厂方法模式面对产品的扩张,需要增加一个产品类和一个产品工厂类。这么做虽然解耦了,当时带来了更多的工作量。
与简单工厂模式相比,工厂方法模式通过多态的运用,保证了开闭原则,但是这是通过多构造一个实例工厂的方式来完成的,这意味着近乎一倍的内存开销,所以在使用这种模式时,工厂内部负责创建的对象,不宜过多,否则得不偿失。
与简单工厂模式的反射优化相比,工厂方法模式,几乎没有任何优势。工厂方法模式能做到的,简单工厂模式的反射优化,基本都能够做到,还少一倍的内存开销。要说优势,也就是通过 new 关键字正向创建对象,比反射的 newInstance() 方法速度更快,而且能在编译阶段发现错误。
所以说,在我看来,工厂方法模式最大的意义,是为其扩展出去的抽象工厂模式(Abstract Factory)铺垫。而实际的应用,简单工厂模式的反射更具优势。
标签:技术 方案 变化 简单工厂 win 最大的 测试 val str
原文地址:http://www.cnblogs.com/jing-an-feng-shao/p/7533443.html