一、抽象工厂方法模式介绍
1. 解决的问题
通过接口的选择,解决在系统产品存在多个产品族,而系统仅消费某一族的产品的问题。
2. 定义
抽象工厂模式是一个围绕超级工厂创建其他工厂的模式,即抽象工厂是一个中心工厂,创建其他工厂的模式。
抽象工厂提供了一个接口,可用于创建每个系列产品的对象。只要代码通过该接口创建对象,那么就不会生产与当前系统已生成的产品类型不一致的产品。
二、抽象工厂方法模式优缺点
1. 优点
- 可以确保同一工厂生产的产品相互匹配。
- 可以避免客户端和具体产品代码的耦合。
- 单一职责原则:将产品生成代码抽取到同一位置,使得产品代码易于维护。
- 开闭原则:向应用程序引入新产品变体时,无需修改客户端代码。
2. 缺点
- 由于采用该模式需要向应用中引入众多接口和类,代码可能会比之前更加复杂。
三、抽象工厂方法模式应用实例:QQ 厘米秀装扮
1. 实例场景
QQ 陪伴我们了 22 年,从 QQ 秀到厘米秀,二维图片到三维立体个人秀,接下来我们以厘米秀的各种装扮作为模拟场景。
以厘米秀的两种套装风格作为示例:
- 现代风:帽子、西装、西裤、皮鞋
- 复古风:礼帽、大衣、长裤、长靴
2. 抽象工厂方法模式实现
2.1 工程结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| abstract-factory-pattern └─ src ├─ main │ └─ java │ └─ org.design.pattern.abstract_factory │ ├─ model │ │ └─ hat │ │ │ ├─ Hat.java │ │ │ ├─ ModernHat.java │ │ │ └─ RetroHat.java │ │ └─ coat │ │ │ ├─ Coat.java │ │ │ ├─ ModernCoat.java │ │ │ └─ RetroCoat.java │ │ └─ pants │ │ │ ├─ Pants.java │ │ │ ├─ ModernPants.java │ │ │ └─ RetroPants.java │ │ └─ shoes │ │ ├─ Shoes.java │ │ ├─ ModernShoes.java │ │ └─ RetroShoes.java │ ├─ factory │ │ ├─ SuitFactory.java │ │ ├─ ModernSuitFactory.java │ │ └─ RetroSuitFactory.java │ | │ └─ service │ ├─ CmShowService.java │ └─ CmShowServiceImpl.java └─ test └─ java └─ org.design.pattern.abstract_factory.test └─ CmShowServiceTest.java
|
2.2 代码实现
2.2.1 基础服饰
帽子
1 2 3 4 5 6
|
public interface Hat { void getStyle(); }
|
现代风帽子
1 2 3 4 5 6 7 8 9
|
public class ModernHat implements Hat { @Override public void getStyle() { System.out.println("现代风帽子"); } }
|
复古风帽子
1 2 3 4 5 6 7 8 9
|
public class RetroHat implements Hat { @Override public void getStyle() { System.out.println("复古风礼帽"); } }
|
2.2.2 装扮套装工厂类
套装工厂
1 2 3 4 5 6 7 8 9
|
public interface SuitFactory { Hat createHat(); Coat createCoat(); Pants createPants(); Shoes createShoes(); }
|
现代风套装工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
public class ModernSuitFactory implements SuitFactory { @Override public Hat createHat() { return new ModernHat(); }
@Override public Coat createCoat() { return new ModernCoat(); }
@Override public Pants createPants() { return new ModerPants(); }
@Override public Shoes createShoes() { return new ModernShoes(); } }
|
复古风套装工厂
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
public class RetroSuitFactory implements SuitFactory { @Override public Hat createHat() { return new RetroHat(); }
@Override public Coat createCoat() { return new RetroCoat(); }
@Override public Pants createPants() { return new RetroPants(); }
@Override public Shoes createShoes() { return new RetroShoes(); } }
|
2.3 测试验证
2.3.1 编写测试类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class CmShowServiceTest { @Test public void getModernSuitCmShow() { SuitFactory suitFactory = new ModernSuitFactory(); CmShowService cmShowService = new CmShowServiceImpl(suitFactory); cmShowService.getSuitStyle(); }
@Test public void getRetroSuitCmShow() { SuitFactory suitFactory = new RetroSuitFactory(); CmShowService cmShowService = new CmShowServiceImpl(suitFactory); cmShowService.getSuitStyle(); } }
|
2.3.2 测试结果
1 2 3 4 5 6 7 8 9 10
| 现代风厘米秀: 现代风帽子 现代风西装 现代风西裤 现代风鞋子 复古风厘米秀: 复古风礼帽 复古风大衣 复古风长裤 复古风长靴
|
四、抽象工厂方法模式结构

- 抽象产品 (Abstract Product) 为构成系列产品的一组不同但相关的产品声明接口。
- 具体产品 (Concrete Product) 是抽象产品的多种不同类型实现。 所有变体 ( 现代风/复古风) 都必须实现相应的抽象产品 (帽子/上衣)。
- 抽象工厂 (Abstract Factory) 接口声明了一组创建各种抽象产品的方法。
- 具体工厂 (Concrete Factory) 实现抽象工厂的构建方法。 每个具体工厂都对应特定产品变体, 且仅创建此种产品变体。
- 尽管具体工厂会对具体产品进行初始化, 其构建方法签名必须返回相应的抽象产品。 这样, 使用工厂类的客户端代码就不会与工厂创建的特定产品变体耦合。 服务 (Service) 只需通过抽象接口调用工厂和产品对象, 就能与任何具体工厂/产品变体交互。
设计模式并不难学,其本身就是多年经验提炼出的开发指导思想,关键在于多加练习,带着使用设计模式的思想去优化代码,就能构建出更合理的代码。
源码地址:https://github.com/yiyufxst/design-pattern-java
参考资料:
小博哥重学设计模式:https://github.com/fuzhengwei/itstack-demo-design
深入设计模式:https://refactoringguru.cn/design-patterns/catalog