Skip to content

抽象工厂模式

亦称: Abstract Factory

1. 简介

抽象工厂模式是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。在实现上,抽象⼯⼚是⼀ 个中⼼⼯⼚,创建其他⼯⼚的模式。

2. 模拟场景

假设你正在开发一款家具商店模拟器。你的代码中包括一些类,用于表示:

  • 一系列相关产品,例如椅子Chair沙发Sofa咖啡桌Coffee­Table
  • 系列产品的不同变体。例如你可以使用现代Modern​维多利亚Victorian装饰风艺术Art­Deco等风格生成椅子、沙发咖啡桌
    Alt text
    你需要设法单独生成每件家具对象,这样才能确保其风格一致。如果顾客收到的家具风格不一样,他们可不会开心。
    Alt text 此外,你也不希望在添加新产品或新风格时修改已有代码。家具供应商对于产品目录的更新非常频繁,你不会想在每次更新时都去修改核心代码的。

3. 解决方案

首先抽象工厂模式建议为系列中的每件产品明确声明接口(例如椅子、沙发或咖啡桌)。然后确保所有产品变体都继承这些接口。例如所有风格的椅子都实现椅子接口;所有风格的咖啡桌都实现咖啡桌接口,以此类推。 Alt text 接下来,我们需要声明抽象工厂——包含系列中所有产品构造方法的接口。例如create­Chair创建椅子、create­Sofa创建沙发和 create­Coffee­Table创建咖啡桌。这些方法必须返回抽象产品类型,即我们之前抽取的那些接口:椅子,沙发和咖啡桌等等。
Alt text 客户端代码可以通过相应的抽象接口调用工厂和产品类。你无需修改实际客户端代码,就能更改传递给客户端的工厂类,也能更改客户端代码接收的产品变体。 Alt text 假设客户端想要工厂创建一把椅子。客户端无需了解工厂类, 也不用管工厂类创建出的椅子类型。无论是现代风格, 还是维多利亚风格的椅子, 对于客户端来说没有分别, 它只需调用抽象 椅子接口就可以了。这样一来, 客户端只需知道椅子以某种方式实现了sit­On坐下方法就足够了。此外, 无论工厂返回的是何种椅子变体, 它都会和由同一工厂对象创建的沙发或咖啡桌风格一致。

总结

抽象工厂定义了用于创建不同产品的接口,但将实际的创建工作留给了具体工厂类。每个工厂类型都对应一个特定的产品变体。
在创建产品时,客户端代码调用的是工厂对象的构建方法,而不是直接调用构造函数(new操作符)。由于一个工厂对应一种产品变体,因此它创建的所有产品都可相互兼容。
客户端代码仅通过其抽象接口与工厂和产品进行交互。该接口允许同一客户端代码与不同产品进行交互。你只需创建一个具体工厂类并将其传递给客户端代码即可。

4. Java中的例子

  • javax.xml.parsers.DocumentBuilderFactory#newInstance()
  • javax.xml.transform.TransformerFactory#newInstance()
  • javax.xml.xpath.XPathFactory#newInstance()
  • 在Spring Boot Data生态中,RepositoryFactory抽象工厂根据不同数据类型(JPA/MongoDB/Redis)生成对应的Repository实现