[把你的理性思维慢慢变成条件反射]
本文,我们讲介绍工厂方法模式,文章主题结构与上位一致。惯例,先来看看我们示例工程的环境:
操作系统:win7 x64
其他软件:eclipse mars,jdk7
-------------------------------------------------------------------------------------------------------------------------------------
经典问题:
首先,请回顾前文我们介绍的计算机问题。在其文中,我们描述其缺点为: 工厂类包含的逻辑判断,需要极高的稳定性,安全性。否则,整个逻辑处理将会发生错误。因此,对于工厂类而言,经常的修改操作,会让其违反“开闭原则”。思路分析:
要点一:使得对工厂了不能违反“开闭原则”
要点二:对客户端仍然保持面向接口编程。
示例工程:
首先,我们先使用简单工厂方法实现计算器的功能,代码放置在base包下,作为参照。具体代码请参考前文《简单工厂模式》。
为满足要点一,二,我们修改代码结构为如下内容:
创建IFactory.java文件,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.one;
public interface IFactory {
Operation CreateOperation();
}
创建AddFactory.java,DivFactory.java,MulFactory.java,SubFactory.java四个文件,在此仅示例AddFactory.java文件,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.one;
public class AddFactory implements IFactory {
@Override
public Operation CreateOperation() {
return new OperationAdd();
}
}
创建OperationAdd.java,OperationDiv.java,OperationMul.java,OperationSub.java四个文件,在此仅示例OperationAdd.java文件,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.one;
public class OperationAdd extends Operation {
public double getResult(Operation op){
double result = op.getNumA()+op.getNumB();
return result;
}
}
创建Window.java文件,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.one;
import java.util.Scanner;
public class Window {
public static void main(String[] args) {
try {
IFactory operFactory1 = new AddFactory();
Operation oper1 = operFactory1.CreateOperation();
oper1.setNumA(10);
oper1.setNumB(23);
System.out.println("加法工厂:"+oper1.getResult(oper1));
IFactory operFactory2 = new SubFactory();
Operation oper2 = operFactory2.CreateOperation();
oper2.setNumA(10);
oper2.setNumB(23);
System.out.println("减法工厂:"+oper2.getResult(oper2));
IFactory operFactory3 = new MulFactory();
Operation oper3 = operFactory3.CreateOperation();
oper3.setNumA(10);
oper3.setNumB(23);
System.out.println("乘法工厂:"+oper3.getResult(oper3));
IFactory operFactory4 = new DivFactory();
Operation oper4 = operFactory4.CreateOperation();
oper4.setNumA(10);
oper4.setNumB(23);
System.out.println("除法工厂:"+oper4.getResult(oper4));
} catch (Exception e) {
e.printStackTrace();
}
}
}
采用工厂方法模式之后带来的优点:
- 移除原有工厂类,并移除其中的多级判断。
- 现在,对任何功能的新增,修改不会影响到其他现有功能。
模式总结:
本例UML结构图:
工厂方法模式标准UML图:
概念总结:
工厂方法模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。组成部分:Product(抽象产品),ConcreteProduct(具体产品),Creator(抽象工厂),ConcreteCreator(具体工厂)四部分组成。
模板代码:
创建ConcreteCreator.java,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.three;
public class ConcreteCreator implements Creator {
@Override
public Product createProduct() {
return new ConcreteProduct();
}
}
创建ConcreteProduct.java文件,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.three;
public class ConcreteProduct implements Product {
@Override
public void createProduct() {
System.out.println("create product");
}
}
创建Creator.java,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.three;
public interface Creator {
public Product createProduct();
}
创建Product.java,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.three;
public interface Product {
public void createProduct();
}
创建Window.java,具体内容如下:
package com.csdn.ingo.gof_FactoryFuncion.three;
public class Window {
public static void main(String[] args) {
Creator creator = new ConcreteCreator();
Product product = creator.createProduct();
product.createProduct();
}
}<span style="font-family:Microsoft YaHei;font-size:14px;">
</span>
问题:简单工厂模式与工厂方法模式有什么不同之处?
答:简单工厂模式的最大优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择条件动态实例化相关的类,对于客户端来说,去除了与具体产品的依赖。对本例而言,采用简单工厂模式,客户端指明一个方法运算符号就可以进行相关运算,而现在,客户端需要明确指明到底实例化那个工厂类才能够进行相关计算。但是,请注意,客户端指明的接口,即在实际使用时,实例化的过程将会延迟到运行时才确定。另外,仔细观察就会发现,本身的工厂类内的逻辑判断只是从一个位置转移到另一个位置,逻辑判断的过程仍然存在于程序当中。使用这种方法,满足了我们再前文中介绍的“迪米特法则”。
反思:
应用场景:
- 在客户端可能需要生成复杂对象时,只需声明抽象工厂即可使用。
- 实现调用方与被调用方的关系解耦,需要实现多态,“里氏代换原则”时
- 具体的实现了需要修改,扩展,维护,运行时切换等。
优点:
- 工厂方法负责创建具体的产品,客户端不在关注创建,实例化,甚至是类名等细节。
- 工厂角色,具体产品实现多态。工厂有权决定声明,实例化哪一种具体对象。
- 当新增或修改新产品时,对现有的功能,及客户端几乎不产生任何影响。
缺点:
- 当存在大量的具体产品类时,需要创建相同数量的工厂类。系统中类的个数将成加倍增加,带来了安装,维护上的成本。
- 为了实现抽象,运行时切换功能等,客户端可能需要额外实现配置文件,并且需要使用反射等技术。
-------------------------------------------------------------------------------------------------------------------------------------
至此,被说了很多遍的设计模式---工厂方法模式 结束
参考资料:
图书:《大话设计模式》
其他博文:http://blog.csdn.NET/lovelion/article/details/7563445