什么时候工厂方法比简单工厂更好,反之亦然?

2024-01-12

我正在阅读《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.

因此,在简单工厂的情况下,客户端将 A 与 B 工厂组合在一起,而使用工厂方法,客户端为它想要的 B 类型选择适当的子类。

他们之间似乎确实没有太多选择。要么您必须选择要与哪个 BFactory 组合 A,要么您必须选择 A 的正确子类来为您提供 B。

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

谢谢大家!

编辑:在我看来,Head First 叙述中给出的解释增加了一点混乱,他们从简单工厂过渡到工厂方法,说(第 119 页)“特许经营店使用你的[简单]工厂来制作披萨,但开始在剩下的过程中采用他们自己的本土程序:他们烘烤的东西有点不同......”他们有一张厨师显然对他的披萨做了一些恶心的事情的照片。

但是,使用简单的工厂并不能让客户端访问 Baker() 方法或该过程的任何其他部分。如果出现任何问题,使用工厂方法没有任何帮助。

所以在我看来,Head First 暗示使用工厂方法而不是简单工厂的原因是假的。


分析不同角色的差异:A 的用户和 A 的提供者。这些模式对这些角色有不同的影响,随着事情随着时间的推移而变化,这些影响很重要。

如果是

A myA = new SomeConcreteA()

A 的客户对 B 的存在一无所知。特定具体 A 的选择可能会受到它使用特定 B 的某些文档或 A 系列的一些完全其他功能的影响。 A 的提供者负责创建具体 A 的所有风格,因此当 B 的种类发生变化时,他们可能需要做一些工作。

如果是

A myA = new A(myBFactory())

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么时候工厂方法比简单工厂更好,反之亦然? 的相关文章

  • 为什么我们需要将 delegate 设置为 self?为什么编译器不默认它?

    I think我完全理解授权的概念 我的问题是 当我们这样做时 class someViewController UIViewController UITableViewDelegate 会吗ever可能我们不想设置tableView de
  • 这个单例能够抵抗序列化和反射攻击吗?

    以下代码是否能够抵抗序列化和反射攻击 public class Example private static Example instance new Example private Example public static Exampl
  • 对多个属性使用一种设置方法 MATLAB

    我有几个属性基本上使用相同的属性set method classdef MyClass properties A B end methods function mc MyClass a b Constructor mc A a mc B b
  • 具有线程安全性的 eventbus 最佳实践

    我的应用程序具有用户交互活动和后台服务 这是修改数据模型的唯一地方 后台服务监听用户所做的操作以及来自网络的传入消息 因此 可能会出现并发问题 我尝试使用处理程序来防止这些问题 对于事件层 我使用 greenrobots Eventbus
  • 继承类中的python __init__方法[重复]

    这个问题在这里已经有答案了 我想为子类提供一些额外的属性 而不必显式调用新方法 那么有没有办法给继承的类一个 init 不重写的类型方法 init 父类的方法 我编写下面的代码纯粹是为了说明我的问题 因此属性等的命名很糟糕 class in
  • 如何将扩展泛型类的实体转换为扩展另一个泛型类的另一个实体

    我正在开发一个面向服务的平台 用于从数据库检索 创建和更新实体 这里的要点是每个 Java 实体都扩展AbstractEntity 例如 我有 MyCar extends AbstractEntity implements Serializ
  • TypeScript 中 C# 类虚拟成员的等效项

    因此 在 C 中 当我创建模型类和延迟加载内容时 我会执行以下操作 public int User ID get set public int Dept ID get set 然后在我的班级稍远一点的地方 我像这样弹出我的虚拟 public
  • 在 Python 中使用类作为命名空间是个好主意吗

    我正在将一堆相关的东西放入一个类中 主要目的是将它们组织到命名空间中 class Direction north 0 east 1 south 2 west 3 staticmethod def turn right d return tu
  • 我担心我添加了太多接口

    我正在构建我的领域模型并继续重构它 正如我所做的那样 我发现我喜欢接口 因为它允许我根据接口为具体类型创建可重用的方法 控制器 视图 但是 我发现每次向域实体之一添加新属性时 我都会创建一个接口 例如 我有一个会员状态从抽象继承的对象Ent
  • 如何通过查看程序集来判断程序是否使用动态调度

    我在 Reddit 上读过一篇文章Herb Stutter JIT 永远不会像原生一样快 http www reddit com r programming comments rr2dj herb stutter jit will neve
  • 面向对象设计的良好参考[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 关联数组与 SplObjectStorage

    我正在编写代码来管理一组独特的对象 该代码的第一个原型使用关联数组 基本上就像我一直这样做的方式一样 然而 我也热衷于利用 PHP 的更现代版本中添加的功能 例如 SplObjectStorage 1 这样做 部分是作为一种学习经验 部分是
  • 句柄类和值类的区别

    我有一些 C 背景 想使用 Matlab 中的类 句柄和值类有什么区别 我知道如果我想定义一个带有重载运算符 例如 和 的矩阵类 我会使用值类 然而 有时 当我选择一个手柄类时 事情似乎只对我有用 MathWorks 提供了一些有关其用途的
  • 为什么Boost在“程序选项”中使用全局函数覆盖来实现自定义验证器

    这个例子 http www boost org doc libs 1 55 0 doc html program options howto html idp163429032显示一个名为validate在全局范围内定义重载函数boost
  • 使用存储库时,ASP.NET MVC 中业务逻辑的最佳位置是什么?

    在 ASP NET MVC 项目中实现数据库存储库时 将业务逻辑放入其中是否正确 或者将逻辑放入控制器类中可能更好 或者使用额外的服务和帮助程序类来操作数据 最终 除了其自己的层 作为 模型 层的一部分 之外 您的业务逻辑没有一个完美的位置
  • 如何在javascript中实现观察者模式?

    你好 我正在尝试在 JavaScript 中实现观察者模式 我的index js document ready function var ironMan new Movie ironMan setTitle IronMan ironMan
  • 为什么Java不支持C中的clrscr这样的函数?

    我有一个问题 对很多人来说可能听起来很愚蠢 但我不能停下来把它发布在这里 因为在互联网上找不到任何东西 为什么java没有我们在C中使用的clrscr之类的函数 如果我创建了一个基于用户输入反复迭代的 java 控制台应用程序 然后如果我想
  • Java:getInstance 与静态

    目的是什么getInstance 在Java中 在我的研究过程中我一直在读getInstance 有助于实现单例设计模式 根据我的理解 这意味着整个程序中只有一个实例 但我不能只使用静态吗 这不是静态的全部意义吗 如果我只有静态方法和字段
  • 通过反思思考工厂设计模式

    我正在对工厂模式进行研发 我开发了下面的代码 现在我知道子类是 Dog 和 Cat 但是如果我想通过在 main 中传递类名来通过反射实现同样的事情 请告诉我该怎么做 爪哇 public abstract class Animal publ
  • 继承php中的属性

    我有一个超类 其中包含用于设置它们的属性和方法 class Super private property function construct set this gt property set 然后我有一个需要使用该属性的子类 class

随机推荐