模型目的:
定义一个基于创建实例的接口,让子类决定实例化哪个类。使类的实例化延迟到该子类。(一般而言是Abstract Factory抽象工厂的实现模式)
适应性:
1.创建实例时封装创建过程,隐藏具体类。
2.可以将逻辑选择创建何种实例的过程封装到方法中。
3.通过代理方式而避免直接创建实例。
模式图:
关注问题:
1.假如由于创建的产品数目有所增长时候,而使子类数目呈现一个庞大数目时候(无法预见产品个数),建议不要使用该模式以及抽象工厂模式。这样会导致工厂难以维护。
2.可以使用其他方法来避免子类的增长,模板(Template)可能是个不错的选择(但这也暴露了相关类型),或者可以使用下文提及的回调工厂的方法(这种方法建议在初始化工厂时候就将回调函数注入到工厂中)。
个人观点:
工厂方法就是一个创建实例的方法,我们可是使用具有参数化的工厂方法,通过参数来返回相应的实例;也可以通过抽象工厂类,派生子类的方法使创建实例延迟到子类。而这也是抽象工厂的一般实现模式。
(在如何区分FactoryMethod与AbstractFactory的问题上,可以参考http://www.cnblogs.com/happyhippy/archive/2010/09/26/1836223.html这份blog文有详细的描述)
而且我认为无论是简单工厂、工厂方法还是抽象工厂,在使用这类创建型工厂模式,我们关心的是以下问题:
1.封装创建实例的过程(使客户通过代理获取实例)、以及客户如何获取实例
2.工厂产品增加问题(即如何扩展工厂来维护开闭原则)
3.如何将可变的及不变的模块分离,使我们更容易维护以及扩展,这也体现了开闭原则。
-----------------------------------------------------------------------------------------------------------
2012/2/4
在工厂方法,与简单工厂的区别就在于其将创建不同种类实例的逻辑选择交个了客户,让客户选择不同工厂来获取实例。
以上这段话取自http://terrylee.cnblogs.com/archive/2006/01/04/310716.html?page=1#commentform。
但在《设计模式》里面提及了一点就是参数化工厂方法的概念,这实际上就是简单工厂。所以我觉得没有必要将简单工厂与工厂方法区分,这或许也是《设》里面没有提及简单工厂的原因,而对于参数工厂方法的做法,最大问题在于若增加新产品的时候,可能会破坏开闭原则。
而如果要在使用参数工厂方法时候维护开闭原则,可以使用一种称为“回调工厂”的方法http://blog.csdn.net/yah99_wolf/archive/2009/03/31/4039493.aspx,通过动态配置工厂的返回实例来达到易于增加产品。也或者可以使用抽象工程类,通过延迟至子类来生成实例的做法,这样只要增加子类就可以达到增加产品实例的效果。