Design Pattern: 简单工厂模式 v.s. 工厂方法模式
2016-09-27 02:10
274 查看
凡是工厂模式,无论是简单的工厂模式还是工厂方法模式,其目的都是封装创建对象的过程,降低客户端代码和产品对象的耦合。使得更换对象的时候,客户端的代码不需要大改。
简单工厂模式通过定义一个简单工厂类(就是一个实现类)的静态函数,在静态函数内定义一个switch case实现动态地选择返回的对象。假如,用实现计算器的代码作为例子。创建一个运算类的接口(方便多态的实现,向上转型):
然后编写具体的实现类,以加法为例:
类似的,定义实现类OperationMinus、OperationMultiply and OperationDivide。
然后创建了一个简单工厂类:
然后每次客户端调用不同的运算时,只需要在调用简单工厂类的getOperation方法并修改输入的字符串参数即可。即可获得相应运算符的对象。代码如下:
但这个方法,有个最大的缺陷在于,如果需要增加运算符,需要修改简单工厂类,不符合封闭、开放原则。根据上述原则,增加功能时,应该修改客户端代码实现。因为对客户端的代码修改是应该开放的,但对工厂类的修改应该是封闭的。所以,诞生了工厂方法模式:
这个模式就是把简单的工厂类分解成多个工厂方法子类,把对象的实例化推迟到了子类中实现。然后,提供了抽象的工厂方法接口,让具体的工厂方法实现类去实现。
然后加法的实现类是:
类似可以定义减、乘、除。
客户端代码是:
这样,每次增加一个运算符时,需要创建增多一个子类,并修改客户端代码即可。符合了封闭、开放原则。
P.S. 关于开放-封闭原则的详述:
开放封闭原则是针对新需求做准备原则。设计工程时,需要考虑未来将要加入的新需求。但是,新需求加入时,不应该修改原来已经写好的代码。取而代之,应该针对新需求再增加一段对应的功能实现代码。典型的实现方法是:利用继承、多态的性质,在同一个功能接口下,针对不同的需求实现不同的类。
简单工厂模式通过定义一个简单工厂类(就是一个实现类)的静态函数,在静态函数内定义一个switch case实现动态地选择返回的对象。假如,用实现计算器的代码作为例子。创建一个运算类的接口(方便多态的实现,向上转型):
interface Operation{ int calculateResult(int a, int b); }
然后编写具体的实现类,以加法为例:
class OperationAdd implements Operation{ public int calculateResult(int a, int b){ return a+b; } }
类似的,定义实现类OperationMinus、OperationMultiply and OperationDivide。
然后创建了一个简单工厂类:
public class SimpleFactory{ public static Operation getOperation(String s){//用到了向上转型 switch(s){ case "add": return new OperationAdd();break; case "minus": return new OperationMinus();break; ...... } } }
然后每次客户端调用不同的运算时,只需要在调用简单工厂类的getOperation方法并修改输入的字符串参数即可。即可获得相应运算符的对象。代码如下:
public static void main(String[] args){ Operation op = SimpleFactory.getOperation("+"); int result = op.calculateResult(1,1); }
但这个方法,有个最大的缺陷在于,如果需要增加运算符,需要修改简单工厂类,不符合封闭、开放原则。根据上述原则,增加功能时,应该修改客户端代码实现。因为对客户端的代码修改是应该开放的,但对工厂类的修改应该是封闭的。所以,诞生了工厂方法模式:
这个模式就是把简单的工厂类分解成多个工厂方法子类,把对象的实例化推迟到了子类中实现。然后,提供了抽象的工厂方法接口,让具体的工厂方法实现类去实现。
interface FactoryMethod{ Operation getOperation(); }
然后加法的实现类是:
public class FactoryMethodAdd{ Operation getOperation(){ return new OperationAdd(); } }
类似可以定义减、乘、除。
客户端代码是:
public static void main(String[] args){ FactoryMethod ins = new FactoryMethodAdd();//接口的引用指向实现类,称为接口回调 Operation op = ins.getOperation(); int result = op.calculateResult(1,1); }
这样,每次增加一个运算符时,需要创建增多一个子类,并修改客户端代码即可。符合了封闭、开放原则。
P.S. 关于开放-封闭原则的详述:
开放封闭原则是针对新需求做准备原则。设计工程时,需要考虑未来将要加入的新需求。但是,新需求加入时,不应该修改原来已经写好的代码。取而代之,应该针对新需求再增加一段对应的功能实现代码。典型的实现方法是:利用继承、多态的性质,在同一个功能接口下,针对不同的需求实现不同的类。
相关文章推荐
- PropertyChangeListener简单理解
- 什么是设计模式
- 设计模式之创建型模式 - 特别的变量问题
- 七、设计模式——装饰模式
- 设计模式总结
- 设计模式之创建型模式
- 浅谈设计模式的学习
- 设计模式---状态模式在web前端中的应用
- Ruby设计模式编程之适配器模式实战攻略
- 实例讲解Ruby使用设计模式中的装饰器模式的方法
- 设计模式中的模板方法模式在Ruby中的应用实例两则
- Ruby设计模式编程中对外观模式的应用实例分析
- 实例解析Ruby设计模式编程中Strategy策略模式的使用
- Ruby中使用设计模式中的简单工厂模式和工厂方法模式
- Ruby使用设计模式中的代理模式与装饰模式的代码实例
- 详解组合模式的结构及其在Ruby设计模式编程中的运用
- C# 设计模式系列教程-建造者模式
- C#编程中使用设计模式中的原型模式的实例讲解
- 使用设计模式中的工厂方法模式进行C#编程的示例讲解
- 实例解析C#设计模式编程中简单工厂模式的使用