【问题标题】:Factory Design Pattern VS Constructor工厂设计模式 VS 构造函数
【发布时间】:2017-07-27 13:32:23
【问题描述】:

我有一个 Product 类,其中包含方法和复杂的数据结构。我将有 8 种类型的产品,它们仅在数据结构的内容上有所不同,没有别的。然后,在我的应用程序中,我需要为 8 种产品类型中的每一种创建一个实例,一次,并且存在的产品类型在运行时不会改变。

什么是最好的方法,为什么?

A) 类产品有 8 个子类。这些子类中的每一个仅定义构造函数。在每个构造函数中,都会为该类型的产品正确创建数据结构。

B) 一个工厂类有 8 个子类。这些子类中的每一个都是 8 种产品中每一种的具体工厂。类 Product 没有子类。每个具体工厂通过创建适当的数据结构并将其作为参数传递给 Product 类的构造函数来创建特定类型的产品。

我一直在回顾工厂设计模式的优势,但对于这种特定情况,我看不出 B 优于 A 的任何优势。我是否遗漏了什么?

【问题讨论】:

  • 我从未见过工厂被子类化。每种类型都有方法。但是,如果您想要一组静态的 Product 对象,工厂更适合在运行时创建这些对象
  • 你的意思是像一个工厂,它的方法返回一个包含 8 个产品的集合?如果它返回一个集合而不是单个对象,它是否被认为是正确的工厂设计模式?
  • "我将有 8 种类型的产品,它们仅在数据结构的内容上有所不同,没有别的。"数据结构是什么?如果它只是一个聚合(例如,Array、LinkedList 等),那么你不需要 8 个子类。
  • 它是另一个类的对象的某种集合。因此,如果没有产品子类,您是否建议选项 B?或者你有什么建议?

标签: oop design-patterns constructor factory factory-pattern


【解决方案1】:

我会选择 A 的变体,也许再加上一个工厂类。工厂旨在创建具有在接口类中定义的方法的类,这样工厂创建的对象的消费者不知道他们正在处理的对象类型,而只知道接口。工厂本身知道要创建什么类型的对象。

如果在给定时间创建什么类型的产品有某种类型的逻辑,则为实现 IProduct 接口的 8 个产品实现一个工厂,并在工厂内部实现创建什么类型的产品的逻辑。

【讨论】:

  • 我试图完全理解您的建议:那么您将如何让应用程序向工厂指定它需要的产品类型?通过某种论证?如果是这样,为什么应用程序不知道产品子类是有利的,而它必须知道要传递给工厂的参数类型......不是一样吗?
  • 不,我建议您将参数传递给工厂,但我不知道您的情况是哪种参数。例如,我在一个实例中有一个工厂模式,它为各种类型的提要提供 XML 解析,并且只为您提供根消息。它可以是 Atom Feed 或 SOAP Web 服务,但工厂获取 URL 并根据它是什么 URL 简单地知道为您提供什么类型的解析器。
  • 例如可以是产品的名称。或者它的条形码。编写接口而不是特定类型的对象只是一种更好的做法。
  • 我明白了。所以让我们想象一下,在我的情况下,我会传递产品的名称。但是如果应用程序需要知道产品名称,那不就和必须知道具体产品子类的名称一样糟糕吗?稍后如果我添加另一个子类,我必须添加另一个名称......
  • 还有一个问题,如果代替 Product 的接口,我会使用已经定义了一些方法的抽象类,这是不好的做法吗?
【解决方案2】:

我相信在工厂设计模式中,您可以从一个工厂创建不同子类的对象。请参阅以下示例-

根据我的说法,使用工厂设计模式的子类方法将是上述场景的更好选择。

【讨论】:

  • 如果我理解正确,您的回答与@kevin-hirst 的回答相同。所以我的问题是:工厂如何知道要生产什么产品?如果我们必须向它传递某种产品“名称”,那么这意味着应用程序必须知道产品名称。这不是和知道产品子类一样糟糕吗?
  • 在通过工厂创建类的新对象时,我相信您需要知道要构建的类的名称或任何显着特征。否则如何创建特定类的对象?工厂不可能自己知道。创建对象后,工厂将返回具有父类引用的特定对象。这一步之后系统不需要知道子类。
【解决方案3】:

您已经提到 - 我将有 8 种类型的产品,它们仅在数据结构的内容上有所不同...。这意味着状态和方法相同,但内容不同。基于此,我觉得这清楚地表明这些不是子类,而是同一类的实例。我认为代码将只包含一个产品类和其中的 8 个实例。工厂是绝对不需要的,它将是不必要的代码。

【讨论】:

  • 是的,你是对的,拥有 8 个实例而不是 8 个子类更有意义。但问题是 8 种不同数据结构的创建很复杂,我不希望客户端应用程序必须知道如何去做。因此构造逻辑可以在两个地方之一:要么在工厂(我的帖子的选项 B)中,要么在 Product 的构造函数中(在这种情况下需要 8 个不同的构造函数,这会导致 8 个子类,即选项 A我的帖子)。
  • 构建器模式在这种情况下可能很有用,@CesarPim。它不需要子类。如果您的数据结构具有复合(以及相应应用的方法),复合模式也可以应用。您应该更新您的问题以指定 8 个数据结构的详细信息。
猜你喜欢
  • 1970-01-01
  • 2019-02-23
  • 2010-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 1970-01-01
  • 2016-01-29
相关资源
最近更新 更多