工厂方法何时比简单工厂好,反之亦然?

时间:2010-06-17 03:06:07

标签: design-patterns oop

通过Head First Design Patterns一书的工作方式。

我相信我理解简单的工厂和工厂方法,但我很难看到工厂方法对简单工厂带来的好处。

如果对象A使用简单工厂来创建其B对象,则客户端可以像这样创建它:

A a = new A(new BFactory());

如果对象使用工厂方法,则客户端可以像这样创建它:

A a = new ConcreteA(); // ConcreteA contains a method for instantiating 
                       // the same Bs that the BFactory above creates, with 
                       // the method hardwired into the subclass of A, ConcreteA.

因此,在简单工厂的情况下,客户端使用B工厂组成A,而使用工厂方法,客户端为其所需的B类型选择适当的子类。

他们之间似乎没有多少选择。要么你必须选择要用A组成的BFactory,要么你必须选择A的正确子类来给你Bs。

在什么情况下哪一个比另一个好?

全部谢谢!

编辑:增加一点混乱IMO是Head First叙述中给出的解释,他们从简单的工厂转换到工厂方法,说(第119页)“特许经营权正在使用你的[简单]工厂制作比萨饼,但是开始在剩下的过程中使用他们自己的本土程序:他们会以不同的方式烘烤东西......“他们有一张厨师的照片,显然他做了一些令人厌恶的比萨饼。

但是没有任何关于使用简单的工厂来让客户访问bake()方法或进程的任何其他部分。并且没有任何关于使用工厂方法如果有任何问题会有所帮助。

因此,在我看来,首先暗示在一家简单的工厂使用工厂方法的原因是假的..

3 个答案:

答案 0 :(得分:2)

分析不同角色的差异:A的用户和A的提供者。这些模式对这些角色有不同的含义,随着时间的推移,这些角色会发生重大变化。

的情况下
A myA = new SomeConcreteA()
A的客户对Bs甚至存在的事实一无所知。特定混凝土A的选择可能会受到某些文档的影响,这些文档使用特定的Bs或A族的其他一些完整的特征。 A的提供者负责创造混凝土A的所有风味,因此当B种变化等事情发生时,他们可能会有工作要做。

的情况下
A myA = new A(myBFactory())

客户现在需要了解B及其工厂,并完全控制使用哪家工厂。提供者给了客户更多的责任,我们可能增加了耦合 - 客户端代码现在明确地依赖于至少一个类。当新的B出现时,A的提供者没有工作要做。

请注意,我们正在注入B工厂,因此在编写客户端单元测试时,我们现在可以更轻松地为Bs提供模拟,因此测试客户端往往更容易。总的来说,我发现由于这个原因,我更频繁地使用这种注射方法。

答案 1 :(得分:1)

比较第117页和第131页的UML图。关键是,简单的工厂决定如何为PizzaStore烘焙比萨饼。工厂方法允许混凝土PizzaFactory决定如何烘焙比萨饼。工厂是关于管理依赖关系。使用构造函数,您必须决定实例化哪个类。使用简单工厂,您可以让具体类来决定实例化哪个类。使用Factory方法,您可以让任何类(可以)决定实例化哪个类。使用抽象工厂,您可以让任何类(可以)决定实例化哪个类,而不管您想要创建什么类型的实例。控制的倒置正在使用你得到的东西,因为决定是在神圣的存在创造了你的时候做出的。

我个人的观点是,GoF的原创设计模式书虽然在解释方面不太好,却有更多真实世界的例子。

答案 2 :(得分:0)

你是正确的,因为从Simple Factory到Factory Method的所有变化都是在Simple Factory中工厂通过构造函数传递的,我们用它来创建我们的对象。在Factory方法中,现在调用抽象工厂类中的抽象方法;但这很有用。由于该方法是抽象的,因此必须在我们想要的子类中实现。我们的子类可以实现它们自己的变体,但某些行为仍然由我们的抽象类强制执行。更强大的是,我们可以通过添加从抽象基类继承的新类来扩展工厂数量而无需修改原始代码。