抽象工厂模式
亦称: Abstract Factory
1. 简介
抽象工厂模式是一种创建型设计模式,它能创建一系列相关的对象,而无需指定其具体类。在实现上,抽象⼯⼚是⼀ 个中⼼⼯⼚,创建其他⼯⼚的模式。
2. 模拟场景
假设你正在开发一款家具商店模拟器。你的代码中包括一些类,用于表示:
- 一系列相关产品,例如椅子Chair、沙发Sofa和咖啡桌CoffeeTable。
- 系列产品的不同变体。例如你可以使用现代Modern、维多利亚Victorian、装饰风艺术ArtDeco等风格生成椅子、沙发和咖啡桌。
你需要设法单独生成每件家具对象,这样才能确保其风格一致。如果顾客收到的家具风格不一样,他们可不会开心。此外,你也不希望在添加新产品或新风格时修改已有代码。家具供应商对于产品目录的更新非常频繁,你不会想在每次更新时都去修改核心代码的。
3. 解决方案
首先抽象工厂模式建议为系列中的每件产品明确声明接口(例如椅子、沙发或咖啡桌)。然后确保所有产品变体都继承这些接口。例如所有风格的椅子都实现椅子接口;所有风格的咖啡桌都实现咖啡桌接口,以此类推。 接下来,我们需要声明抽象工厂——包含系列中所有产品构造方法的接口。例如createChair创建椅子、createSofa创建沙发和 createCoffeeTable创建咖啡桌。这些方法必须返回抽象产品类型,即我们之前抽取的那些接口:椅子,沙发和咖啡桌等等。
客户端代码可以通过相应的抽象接口调用工厂和产品类。你无需修改实际客户端代码,就能更改传递给客户端的工厂类,也能更改客户端代码接收的产品变体。
假设客户端想要工厂创建一把椅子。客户端无需了解工厂类, 也不用管工厂类创建出的椅子类型。无论是现代风格, 还是维多利亚风格的椅子, 对于客户端来说没有分别, 它只需调用抽象 椅子接口就可以了。这样一来, 客户端只需知道椅子以某种方式实现了
sitOn
坐下方法就足够了。此外, 无论工厂返回的是何种椅子变体, 它都会和由同一工厂对象创建的沙发或咖啡桌风格一致。
总结
抽象工厂定义了用于创建不同产品的接口,但将实际的创建工作留给了具体工厂类。每个工厂类型都对应一个特定的产品变体。
在创建产品时,客户端代码调用的是工厂对象的构建方法,而不是直接调用构造函数(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实现