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

问题

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

在那里我读到了有关工厂,工厂方法和抽象工厂的信息,但是它们很混乱,我对定义并不清楚。根据定义

Factory - 创建对象而不将实例化逻辑暴露给客户端,并通过公共接口引用新创建的对象。 Factory Method Factory方法的简化版本 - 定义用于创建对象的接口,但让子类决定实例化哪个类,并通过公共接口引用新创建的对象。抽象工厂 - 提供用于创建相关对象族的界面,而无需明确指定其类。

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

任何人都可以告诉我

  • 这三种模式如何相互不同?
  • 何时使用哪个?
  • 如果可能的话,还有与这些模式相关的任何java示例?

#1 热门回答(177 赞)

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

假设你希望能够创建两种水果:Apple和Orange。

###工厂

工厂是"固定的",因为你只有一个没有子类化的实现。在这种情况下,你将拥有这样的类:

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 热门回答(16 赞)

Factory-单独的Factory类创建复杂对象。

Ex:FruitFactory类创建Fruit的对象

class FruitFactory{

public static Fruit getFruit(){...}

}

工厂方法-而不是工厂的整个单独类,只需在该类中添加一个方法作为工厂。

例如:

Calendar.getInstance() (Java's Calendar)

摘要工厂方法-工厂工厂

例如:假设我们想为计算机零件建造工厂。因此有几种类型的计算机,如笔记本电脑,台式机,服务器。

因此,对于每种计算机类型,我们需要工厂。因此,我们创建了一个高级工厂,如下所示

ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

现在这3个本身又是工厂。 (你将处理PartFactory本身,但在引擎盖下,将根据你在抽象工厂中提供的内容进行单独实现)

Interface-> PartFactory. getComputerPart(String s), 
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Usage:
new ComputerTypeAbstractFactory().getFactory("Laptop").getComputerPart("RAM")

编辑:根据评论中的异议编辑,为抽象工厂提供精确的界面。


#3 热门回答(15 赞)

这三种模式如何相互不同?

**出厂商:**创建对象而不将实例化逻辑暴露给客户端。

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

**Abstract Factory:**提供了一个接口,用于创建相关或从属对象的族,而无需指定其具体类。

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

何时使用哪个?

**工厂:**客户端只需要一个类,而不关心它正在实现哪个具体实现。

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

**AbstactFactory:**当你的系统必须创建多个系列的产品或你想要提供产品库而不暴露实现细节时。

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

如果可能,还有与这些模式相关的任何java示例?
Factory and FactoryMethodIntent:
定义用于创建对象的接口,但让子类决定实例化哪个类。 Factory Method允许类将实例化推迟到子类。

UML diagram

enter image description here

Product:它定义Factory方法创建的对象的接口。

ConcreteProduct:实现产品界面

创建者:声明工厂方法

ConcreateCreator:实现Factory方法以返回ConcreteProduct的实例

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

代码段:
Factory Pattern. When to use factory methods?
与其他创作模式比较:

  • 设计从使用工厂方法开始(更简单,更可定制,子类激增),并逐渐向抽象工厂,原型或构建器发展(更灵活,更复杂),因为设计师发现需要更多灵活性的地方
  • 抽象工厂类通常使用工厂方法实现,但也可以使用Prototype实现

参考文献:Sourcemaking design-patterns