22:31:27 2014-01-11
个人认为GOF中对Factory Method描述的很清楚,所以会大量引用其内容。
Factory Method in GOF
-
Intent
Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.
定义了一个用于创建对象的接口,由子类决定实例化哪个类。工厂方法把一个类的实例化延迟到其子类。
工厂方法模式较简单工厂模式,修改时关闭的,扩展时开放的,完全符合开放-封闭原则。
-
Also Known As
Virtual Constructor
虚构造器
-
Motivation
Two key abstractions in this framework are the classes Application and Document.
Because the particular Document subclass to instantiate is application-specific, the Application class can‘t predict the subclass of Document to instantiate—the Application class only knows whena new document should be created, not what kindof Document to create. This creates a dilemma: The framework must instantiate classes, but it only knows about abstract classes, which it cannot instantiate.
The Factory Method pattern offers a solution. It encapsulates the knowledge of which Document subclass to create and moves this knowledge out of the framework.
因为被实例化的特定Document子类是与特定应用相关的,所以Application类不可能预测到哪个Document子类将被实例化———Application类仅知道一个新的文档何时应被创建,而不知道哪一种Document将被创建。这就产生了一个尴尬的局面:框架必须实例化类,但是它只知道不能被实例化的抽象类。
Factory Method 模式提供了一个解决办案。它封装了哪一个Document.子类将被创建的信息并将这些信息从该框架中分离出来,如下页上图所示(防GOF)。Application和Document 也可为关联。
Application subclasses redefine an abstract CreateDocument operation on Application to return the appropriate Document subclass. Once an Application subclass is instantiated, it can then instantiate application-specific Documents without knowing their class. We call CreateDocument a factory method because it‘s responsible for "manufacturing" an object.
Application 的子类重定义 Application 的抽象操作 CreateDocument 以返回适当的 Document 子类对象。一旦一个 Application子类实例化以后,它就可以实例化与应用相关的文档,而无需知道这些文档的类。我们称 CreateDocument 是一个工厂方法( factory method) ,因为它负责“生产”一个对象。
-
Applicability
Use the Factory Method pattern when
● a class can‘t anticipate the class of objects it must create.
● a class wants its subclasses to specify the objects it creates.
● classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.
在下列情况下可以使用 Factory Method模式:
● 当一个类不知道它所必须创建的对象的类的时候。
● 当一个类希望由它的子类来指定它所创建的对象的时候。
● 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
-
Structure
-
代码
代码就不贴了,不是不能也不是不愿而是不必。网上误导的已经够多了,我解释下"而是不必",你们就会心领神会了。
假定有CA/ConcreteCA* 和 CB/ConcreteCB*。CA要使用CB。
● 简单工厂模式
//根据条件创建CB
CA.CreatB = new ConcreteCB_N();
//CA使用CB
CB* pcb= CA.CreatB;
CA知悉ConcreteCB*,自己创建CB并使用CB。
就此关联性举个例子。
假如你有一个亲身亲为的领导,自己要吃饭了。不是差遣你点外卖,而是自己点。
● 工厂方法模式
//根据条件创建CB
ConcreteCA_N.CreatB = new ConcreteCB_N();
ConcreteCA_N.CreatB即为Factory Method。
//CA使用CB
CB* pcb= CA.CreatB; //CA.CreatB 由 ConcreteCA_N.CreatB实现
CA不用知悉ConcreteCB*,只管使用CB。
这个就好比你遇上一个甩手领导了,自己要吃饭了,就差遣你点外卖。
● 总结
通过以上比较可知,两者最关键的区别就是创建时机不同。这就是"而是不必"的原因了。
所以网上用代码来阐述的例子,总是让人感觉在抽象、纯虚里绕来绕去。设计模式是为应用场景服务的,精确定位应用场景才能正确应用。
软件是人的思想衍生,也是模拟人的解决思维。我们应该人性地看待软件,主导软件,把人的灵魂注入软件,而不是从软件中汲取精神。