设计模式:工厂 vs 工厂方法 vs 抽象工厂

我正在从网站上阅读设计模式

在那里,我读到了关于工厂,工厂方法和抽象工厂的信息,但它们是如此令人困惑,对定义不清楚。根据定义

工厂 - 在不向客户端公开实例化逻辑的情况下创建对象,并通过公共接口引用新创建的对象。是工厂方法的简化版本

工厂方法 - 定义用于创建对象的接口,但让子类决定要实例化的类,并通过公共接口引用新创建的对象。

抽象工厂 - 提供用于创建相关对象族的接口,而无需显式指定它们的类。

我还查看了有关抽象工厂与工厂方法的其他堆栈溢出线程,但那里绘制的UML图使我的理解更加糟糕。

任何人都可以告诉我

  1. 这三种模式有何不同?
  2. 何时使用哪个?
  3. 如果可能的话,是否有任何与这些模式相关的java示例?

答案 1

所有三种工厂类型都做同样的事情:它们是“智能构造函数”。

假设您希望能够创建两种水果:苹果和橙子。

工厂是“固定的”,因为你只有一个没有子类化的实现。在本例中,您将有一个如下类:
class FruitFactory {

  public Apple makeApple() {
    // Code for creating an Apple here.
  }

  public Orange makeOrange() {
    // Code for creating an orange here.
  }

}

用例:构造 Apple 或 Orange 有点太复杂了,无法在构造函数中处理。

工厂方法

工厂方法通常在类中有一些泛型处理,但希望改变实际使用的水果类型时使用。所以:
abstract class FruitPicker {

  protected abstract Fruit makeFruit();

  public void pickFruit() {
    private final Fruit f = makeFruit(); // The fruit we will work on..
    <bla bla bla>
  }
}

...然后,您可以通过在子类中实现工厂方法来重用 中的常见功能:FruitPicker.pickFruit()

class OrangePicker extends FruitPicker {

  @Override
  protected Fruit makeFruit() {
    return new Orange();
  }
}

抽象工厂

抽象工厂通常用于依赖注入/策略之类的事情,当你希望能够创建一整个需要“同类”的对象家族,并具有一些共同的基类时。这是一个模糊的与水果有关的例子。这里的用例是,我们希望确保我们不会意外地在Apple上使用OrangePicker。只要我们从同一家工厂获得水果和采摘器,它们就会匹配。
interface PlantFactory {
  
  Plant makePlant();

  Picker makePicker(); 

}

public class AppleFactory implements PlantFactory {
  Plant makePlant() {
    return new Apple();
  }

  Picker makePicker() {
    return new ApplePicker();
  }
}

public class OrangeFactory implements PlantFactory {
  Plant makePlant() {
    return new Orange();
  }

  Picker makePicker() {
    return new OrangePicker();
  }
}

答案 2
  1. 这三种模式有何不同?

厂:在不向客户端公开实例化逻辑的情况下创建对象。

工厂方法:定义用于创建对象的接口,但让子类决定要实例化的类。Factory 方法允许类将实例化推迟到子类

抽象工厂:提供一个接口,用于创建相关或依赖对象的族,而无需指定其具体类。

AbstractFactory模式使用组合将创建对象的责任委托给另一个类,而Factory方法设计模式使用继承并依靠派生类或子类来创建对象

  1. 何时使用哪个?

厂:客户端只需要一个类,而不关心它得到的具体实现。

工厂方法:客户端不知道在运行时需要创建哪些具体的类,但只想获得一个可以完成这项工作的类。

AbstactFactory:当您的系统必须创建多个产品系列,或者您希望在不公开实现细节的情况下提供产品库时。

抽象工厂类通常使用工厂方法实现。工厂方法通常在模板方法中调用。

  1. 如果可能的话,是否有任何与这些模式相关的java示例?

工厂和工厂方法

意图:

定义用于创建对象的接口,但让子类决定要实例化的类。工厂方法允许类将实例化推迟到子类。

UML 图

enter image description here

产品:它定义了 Factory 方法创建的对象的接口。

混凝土产品:实现产品接口

造物主:声明工厂方法

创建创建者:实现 Factory 方法以返回 ConcreteProduct 的实例

问题陈述:使用定义游戏界面的工厂方法创建游戏工厂。

代码片段:

工厂模式。何时使用工厂方法?

与其他创建模式的比较:

  1. 设计从工厂方法开始(更简单,更可定制,子类激增),并随着设计人员发现需要更多灵活性的地方而向抽象工厂,原型或构建器(更灵活,更复杂)发展

  2. 抽象 工厂类通常使用工厂方法实现,但它们也可以使用原型实现

进一步阅读的参考:源制作设计模式


推荐