首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >设计模式:工厂对工厂方法与抽象工厂

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

Stack Overflow用户
提问于 2012-10-23 11:16:36
回答 9查看 117.9K关注 0票数 244

我在读一个网站的设计模式

在那里,我读到了工厂,工厂方法和抽象工厂,但他们是如此混乱,不清楚的定义。根据定义

工厂-在不向客户端公开实例化逻辑的情况下创建对象,并通过公共接口引用新创建的对象。是工厂方法的简化版本 工厂方法-定义用于创建对象的接口,但让子类来决定实例化哪个类,并通过公共接口引用新创建的对象。 抽象工厂-提供了创建一系列相关对象的接口,而没有显式地指定它们的类。

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

谁能告诉我

  1. 这三种模式有何不同?
  2. 什么时候用哪种?
  3. 如果可能的话,还有与这些模式相关的java示例吗?
EN

回答 9

Stack Overflow用户

发布于 2012-10-23 12:12:15

这三种工厂类型都是一样的:它们是一个“智能构造函数”。

假设你想要创造两种水果:苹果和橘子。

工厂

工厂是“固定的”,因为您只有一个没有子类的实现。在本例中,您将拥有这样一个类:

代码语言:javascript
复制
class FruitFactory {

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

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

}

用例:在构造函数中构造Apple或Orange有点太复杂了。

工厂法

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

代码语言:javascript
复制
abstract class FruitPicker {

  protected abstract Fruit makeFruit();

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

...then您可以通过在子类中实现工厂方法来重用FruitPicker.pickFruit()中的公共功能:

代码语言:javascript
复制
class OrangePicker extends FruitPicker {

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

抽象工厂

抽象工厂通常用于像依赖注入/策略这样的东西,当您想要创建一个完整的对象族,这些对象必须是“同类”的,并且有一些公共基类。下面是一个与水果有关的模糊例子。这里的用例是,我们希望确保我们不会意外地在苹果上使用OrangePicker。只要我们从同一家工厂得到水果和柳条,它们就会相配。

代码语言:javascript
复制
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();
  }
}
票数 348
EN

Stack Overflow用户

发布于 2016-03-07 18:41:09

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

工厂:创建对象而不向客户端公开实例化逻辑。

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

抽象工厂:提供了一个接口,用于在不指定具体类的情况下创建相关或依赖对象的系列。

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

  1. 什么时候用哪种?

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

工厂方法:客户端不知道它需要在运行时创建哪些具体的类,但只想得到一个执行任务的类。

当您的系统必须创建多个产品系列或您希望提供一个产品库而不公开实现细节时,AbstactFactory:

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

  1. 如果可能的话,还有与这些模式相关的java示例吗?

工厂与FactoryMethod

意图:

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

UML图

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

ConcreteProduct:实现产品接口

Creator:声明Factory方法

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

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

代码片段:

工厂模式。什么时候使用工厂的方法?

与其他创造模式的比较:

  1. 设计首先使用工厂方法(不那么复杂、更可定制、子类激增),然后向抽象工厂、原型或Builder (更灵活、更复杂)发展,因为设计人员发现哪里需要更多的灵活性
  2. 抽象工厂类通常使用Factory方法实现,但也可以使用Prototype实现

进一步阅读参考资料:采购设计.模式

票数 30
EN

Stack Overflow用户

发布于 2012-10-23 11:47:05

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

示例:创建果树对象的FruitFactory类

代码语言:javascript
复制
class FruitFactory{

public static Fruit getFruit(){...}

}

Factory方法-而不是整个单独的工厂类,只需将该类本身中的一个方法作为工厂添加即可。

例如:

代码语言:javascript
复制
Calendar.getInstance() (Java's Calendar)

抽象工厂-工厂工厂

例句:让我们说,我们想建立电脑零件的工厂。因此,有几种类型的计算机,如笔记本电脑,桌面,服务器。

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

代码语言:javascript
复制
ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

现在,这3人本身又成了工厂。(您将处理PartFactory本身,但在幕后,将根据抽象工厂中提供的内容进行单独的实现)

代码语言:javascript
复制
  Interface-> PartFactory. getComputerPart(String s), 
Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.

Usage:
new ComputerTypeAbstractFactory().getFactory(“Laptop”).getComputerPart(“RAM”)

编辑:编辑,为抽象工厂提供准确的接口,根据评论中的反对意见。

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13029261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档