转:http://blog.csdn.net/zhengzhb/article/details/7348707
————————————————————————————————————
1.前言
设计模式,各具特色,今天在此总结一下常见模式中 简单工厂模式与工厂方法模式的区别与联系
2.两种模式概要
1. 简单工厂模式
对于简单工厂模式的介绍,请参考我的另外一篇博客 代码无错就是优?----简单工厂模式
2. 工厂方法模式
- 工厂方法模式又称工厂模式,也叫虚拟构造器模式属于类的创建型模式
- 在工厂方法模式中,父类负责定义创建对象的公共接口,而子类则负责生成具体的对象.这样做的目的是将类的实例化操作延迟到子类中完成.由子类决定实例化哪个类
工厂方法模式结构图:
3.两种模式的对比
对于这两种模式,请参照下表 :
简单工厂模式 |
工厂方法模式 |
|
类型 |
创建型模式 |
创建型模式 |
概念 |
简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。 |
定义了一个用于创建对象的接口,让子类决定实例化哪一个类, 工厂方法使一个类的实例化延迟到其子类 |
特点 |
无需了解这些对象是如何创建如何组织的 |
粒度很小的设计模式,是简单工厂模式的衍生 一个抽象工厂对应一个抽象产品 |
优点 |
1. 含有必要的逻辑判断 ,随时可以创建产品类的实例 2. 客户端可以避免直接创建产品对象的责任 3. 耦合性低,明确区分了各自的职责 4. 有利于软件体系结构的优化 |
1. 克服了简单工厂模式的缺点 2. 具体工厂类只完成单一的任务 3. 代码简洁 4. 完全满足OCP,有很好的扩展性 |
缺点 |
1. 当产品有复杂的多层次等级结构时,工厂类只有自己,以不变应万变 2. 工厂类集中了所有产品的创建逻辑,一旦不能正常工作,整个系统都收到影响 3. 系统扩展困难 4. 违背了开放—封闭原则 |
1. 不易于维护 2. 当同时需要修改多个产品类时,修改麻烦 |
适用范围 |
1. 创建的对象比较少 2. 客户只知道传入了工厂类的方法 |
1. 当一个类不知道它所必须创建对象的类或一个类希望由子类来指定它所创建的对象时 2. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化时 |
共同点 |
本质都是将不变的部分提取出来,将可变的部分留作接口,以达到最大程度上的复用。 |
4.两种模式结构图
此处的结构图以及下面的对比代码都是以一个简单的计算器功能为例子,包含四种基本运算加、减、乘、除。
1.简单工厂模式
2.工厂方法模式
注释:
在简单工厂模式中,一个工厂类处于对产品类进行实例化的中心位置,它知道每一个产品类的细节,并决定适合哪一个产品应当被实例化.简单工厂模式的 优点是能够使客户端独立于产品的创建过程,并且在系统中引入新产品时,不必对客户端进行修改.缺点是当有新产品加入到系统的时候,必须修改工厂类,以加入必要的处理逻辑. 简单工厂模式的致命缺点就是处于核心地位的工厂类, 因为一旦它无法确定要对哪个类进行实例化,就无法使用该模式,而工厂方法模式则可以很好的解决这一问题
在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户端隐藏了哪种具体产品类将被实例化这一细节,工厂方法模式的核心是一个抽象工厂类, 各种具体工厂类通过抽象工厂类将工厂方法继承下来, 如此使得客户可以只关心抽象产品和抽象工厂,完全不用理会会返回哪一种具体产品,也不用关心它是如何被具体工厂创建的
5.两种模式代码
1.简单工厂模式
[csharp] view plaincopyprint?
- public class OperationFactory ///创建了一个工厂,用户已输入符号,工厂就会判断怎么计算了
- {
- public static Operation createOperate(string operate)
- {
- Operation oper = null;
- switch (operate)
- {
- case "+":
- oper = new OperationAdd();
- break;
- case "-":
- oper = new OperationSub();
- break;
- case "*":
- oper = new OperationMul();
- break;
- case "/":
- oper = new OperationDiv();
- break;
- }
- return oper;
- }
- }
- }
public class OperationFactory ///创建了一个工厂,用户已输入符号,工厂就会判断怎么计算了 { public static Operation createOperate(string operate) { Operation oper = null; switch (operate) { case "+": oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; case "*": oper = new OperationMul(); break; case "/": oper = new OperationDiv(); break; } return oper; } } }
2. 工厂方法模式
[csharp] view
plaincopyprint?
- interface Ifactory
- {
- Operation CreateOperation();
- }
- class SubFactory : Ifactory //减法类工厂
- {
- public Operation CreateOperation()
- {
- return new OperationSub();
- }
- }
- class AddFactory : Ifactory //加法类工厂
- {
- public Operation CreateOperation()
- {
- return new OperationAdd();
- }
- }
- class MulFactory : Ifactory //乘法类工厂
- {
- public Operation CreateOperation()
- {
- return new OperationMul();
- }
- }
- class DivFactory : Ifactory //除法类工厂
- {
- public Operation CreateOperation()
- {
- return new OperationDiv();
- }
- }
interface Ifactory { Operation CreateOperation(); } class SubFactory : Ifactory //减法类工厂 { public Operation CreateOperation() { return new OperationSub(); } } class AddFactory : Ifactory //加法类工厂 { public Operation CreateOperation() { return new OperationAdd(); } } class MulFactory : Ifactory //乘法类工厂 { public Operation CreateOperation() { return new OperationMul(); } } class DivFactory : Ifactory //除法类工厂 { public Operation CreateOperation() { return new OperationDiv(); } }
注释:
对于两种模式在代码方面的应用看 ,简单工厂模式,如果需要添加功能需要修改 工厂类,而工厂方法模式实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题还是存在的,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端代码来进行,你若要加功能,本来是修改工厂类,现在修改的是客户端,工厂模式实际是是简单模式的一种演化。 工厂模式有效的避免了简单工厂模式中违背开放--封闭原则的限制,同时也加你了耦合性,增加了扩展性 。也就是说工厂方法模式 是简单工厂模式的进一步推广!
其实无论应用哪种设计模式,本质上都是提出不变的东西,将可变的东西作为接口,以达到最大程度上的复用,和扩展,而在开发过程中我们该用什么模式,就得根据需要来确定了。每种模式各有自己的利弊好坏。而如何利用这些模式,什么时间去用,就看我们的技术了吧! 这也就是菜鸟和大神的区别吧! 大神是用最少的投资 发挥最大的效益! 这就是我们这些人的奋斗目标 !
本篇系统的总结了一下两种模式,欢迎交流指导!