【问题标题】:If I use abstract class instead of interface while implementing factory pattern. Would it still be a factory pattern?如果我在实现工厂模式时使用抽象类而不是接口。它仍然是工厂模式吗?
【发布时间】:2015-07-17 14:00:15
【问题描述】:

例如:http://www.tutorialspoint.com/design_pattern/factory_pattern.htm

如果我在抽象类 Shape 上更改接口形状,请创建具体类以扩展 Shape 并使 Shape 工厂返回 Shape 抽象类类型对象。它仍然是工厂模式吗?

【问题讨论】:

  • 简短回答:是的。实际上,从 Java 8 开始,您可以为接口中的方法提供默认实现,与抽象类的唯一区别是构造函数(您显然不会使用)和应该是私有的字段,因此几乎没有区别。
  • 是的,也是一个带有实现默认方法的 java 8 接口。提供带有接口的默认基类确实经常发生(即在摇摆中),并且其本身是一种有用的、支持性的做法。也许尝试只制作final 公共方法,表示规定的行为/附加信息。优势之一:您可以使用 protected 方法来覆盖。
  • 您可能还对Abstract Factory vs Factory Method感兴趣。

标签: java design-patterns


【解决方案1】:

我会同意的。

让我们看一下工厂方法模式的定义:

工厂方法模式是一种创造性的模式,它使用工厂方法来处理创建对象的问题,而无需指定将要创建的对象的确切类

这种模式背后的动机是将对象创建与使用对象的客户端分开。客户应向工厂提供规范,但具体如何构建对象由工厂抽象出来。

如果这是一个接口或抽象类是特定于情况的实现细节,只要你的工厂实现让你实现模式背后的动机。

如果这些陈述中的任何一个适用于您的情况,请考虑使用抽象类:

  • 您希望在几个密切相关的类之间共享代码。

  • 您希望扩展抽象类的类具有许多公共方法或字段,或者需要公共以外的访问修饰符(例如受保护和私有)。

  • 您要声明非静态或非最终字段。这使您能够定义可以访问和修改它们所属对象的状态的方法。

如果这些陈述中的任何一个适用于您的情况,请考虑使用接口:

  • 您希望不相关的类会实现您的接口。例如,接口 Comparable 和 Cloneable 由许多不相关的类实现。

  • 您想指定特定数据类型的行为,但不关心谁实现了它的行为。

  • 您想利用类型的多重继承。

在某些实现中,使用抽象类而不是工厂创建的产品的接口可能更有意义。如果所有产品之间有一组共享的特性/行为,那么将它们放入基本抽象类中确实有意义。即使产品是由不同的工厂生产的,这也适用。

归结为:您是否希望引入耦合以及引入耦合是否有意义 产品之间与否? 最终,客户将得到相同的结果——产品基于规范构建,构造细节被抽象掉。

【讨论】:

    【解决方案2】:

    当谈到这些差异时,答案总是可以是肯定的,也可以是否定的。设计模式不是任何一种精确的规范,它们更像是一组最佳和推荐的实践,它们的实现因情况而异。

    在我看来,答案是否定的,从技术上讲,这不是工厂模式。只要它解决了您的用例并使代码具有可读性和可维护性(试图从字面上遵守设计模式通常会导致误用它们并导致过度架构),就不必如此。

    如果我们查看抽象工厂模式(在链接页面中工厂模式的正下方),我们会发现它是一个用于创建工厂的工厂。现在假设我们有两个Shape 工厂可以由AbstractFactory 创建:ShapeFactory2DShapeFactory3D,都产生Shape 对象。

    如果Shape 是抽象类,那么您将强制 2D 和 3D 对象继承相同的实现,尽管这可能没有意义(它们可以以完全不同的方式实现)。

    因此,从技术上讲,为了使其真正成为工厂模式,必须不存在关于实现细节的假设,这意味着不应在工厂接口级别使用包含部分实现的抽象类。

    当然你可以让Abstract2DShapeAbstract3DShape抽象类实现Shape;关键是您可以创建使用 Shape,而无需知道它是 2D 还是 3D 形状。

    【讨论】:

    • 但是 OP 没有询问抽象工厂模式,因此该答案中 6 段中有 4 段与该问题无关。
    • 答案描述了Factory Pattern在应用程序中是如何使用的。 抽象工厂模式只是工厂如何使用的一个例子(最终它们将以某种方式使用,否则实现它们是没有意义的)。
    猜你喜欢
    • 2018-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多