the5fire

关注Python、Django、Vim、Linux、Web开发、团队管理和互联网--Life is short, we need Python.


重温设计模式之工厂方法

作者:the5fire | 标签:     | 发布:2011-05-30 9:34 a.m. | 阅读量: 6640, 6446
在前面《重温设计模式之建造者模式(Builder)》一文中,从模板方法(Template Method)推演到建造者模式(Builder)的过程中我们发现从模板方法到建造者或者是工厂方法其实只有一步之距。
但归咎于两者的侧重点并不一样,模板方法更注重“定义算法骨架”然后是把算法的实现延迟到子类中,而工厂方法则是“定义创建对象的接口”,然后也是把要创建对象的实例化延迟到子类中。
但是这并不妨碍我们由模板方法推演到工厂方法,我们不能被定义束缚,灵活才是设计模式要做的。
最后得到这么个结果:

(路人甲:我擦,这是个什么模式?)
这个模式其实已经不是模板方法了,因为它在AbstractClass这个父类中没有了算法骨架;也不是工厂方法,因为它最后并不创建对象。
那么这是个什么东东呢,其实就是自己随便推演出来的,在写这篇文章之前其实没有构思这么一个模式的,随写随构思得到这样的结果。
这个模式的优点在哪呢?
我个人从理论上分析这样等于是对模板方法的灵活性进行了扩充,这样扩充完毕之后如果添加新的模板方法的实现不会打破……
推演到这里我发现上面的思路是错误的,错误在于忽略了模板方法的特性,TemplateMethod()方法不需要移到另外一个类中,只需要在父类中就可以,通过一个父类可以控制多个子类,然后通过Spring的注入也可以遵循“开-闭”原则。

再重新屡一下思路:之所以要从模板方法推演到工厂方法,原因在于我想通过工厂方法将模板方法不遵循“开-闭”原则的地方去掉,但是现在发现其实模板方法并没有违反“开-闭”原则。另外模板方法中的具体步骤的实现虽然延迟到子类中,但是整个算法骨架依然是由父类控制,这个特点使得模板方法不需要额外的控制类来完成对其子类的操作。

再次回到工厂方法上来,既然无法由模板方法很恰当的推出来工厂方法,那就直接开始工厂方法,但是要谨记为什么不能由模板方法推到工厂方法,这样就可以很好的理解,为什么工厂方法需要这么多类来共同协调完成一个对象的创建。

还是给出工厂方法的官方定义:工厂方法模式(Factory Method),定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类得实例化延迟到其子类。
下面是由Rose 2003自动生成的一个工厂方法的类结构图:

这个只是最简单的一个工厂模式结构,对于工厂,可以有很多层的抽象,也可以有很多层的实现,对于Product也是如此。
前面已经提到,工厂方法的核心是:定义一个用于创建对象的接口。
这么做的好处就是,在引入新的产品之后我们不需要修改任何代码就能够满足我们的需求,只需要添加对应的产品类和产品工厂类。然后通过注入或者反射来完成对应的操作。
具体的实现代码,看到这个类图也就很好实现了,相关的例子可以参考《大话设计模式》以及《java与模式》,这两个都是比较详细、通俗易懂的。
关于工厂方法的实际应用,目前在SSH架构的项目中,好像不需要明显的使用出来,如果我需要创建某一个抽象产品,我通过注入就可以实现,但是这个就比较局限了,也就是说在项目运行中我只能得到一个产品,如果需要别的产品的话我要修改spring的配置文件,然后重启项目。
当然对于简单的或者说逻辑比较简单的项目,这样足以,然而对于稍微复杂点的项目只需要使用简单工厂就可以完成,毕竟工厂方法的使用是增加类来完成的。如果项目整体的扩展性和灵活性要求较高的话,使用工厂方法是个不错的选择。
- from the5fire.com
----EOF-----

微信公众号:Python程序员杂谈


其他分类: