目录
一、工厂模式的核心分类
二、1. 简单工厂模式
核心思想
适用场景
无人售货柜项目案例:支付渠道创建
步骤 1:定义产品接口
步骤 2:实现具体产品
步骤 3:创建简单工厂类
步骤 4:客户端调用
优缺点
三、2. 工厂方法模式
核心思想
适用场景
无人售货柜项目案例:IoT 设备连接工厂
步骤 1:定义产品接口
步骤 2:实现具体产品
步骤 3:定义抽象工厂接口
步骤 4:实现具体工厂
步骤 5:客户端调用
优缺点
四、3. 抽象工厂模式
核心思想
适用场景
无人售货柜项目案例:售货柜配置工厂
步骤 1:定义多个产品等级接口
步骤 2:实现具体产品(分产品族)
步骤 3:定义抽象工厂接口(对应产品族)
步骤 4:实现具体工厂(对应具体产品族)
步骤 5:客户端调用
优缺点
五、三种工厂模式对比
六、工厂模式在无人售货柜项目中的落地建议
七、工厂模式的核心设计原则
工厂模式是创建型设计模式的核心模式之一,核心思想是“封装对象的创建过程,将对象创建与使用分离”,降低代码耦合度,提高扩展性。
在实际开发中(比如无人售货柜项目的设备实例化、支付渠道对接),工厂模式被广泛用于统一管理复杂对象的创建逻辑。
一、工厂模式的核心分类
工厂模式分为 3 种核心形态,从简单到复杂逐步升级,满足不同场景的需求:
- 简单工厂模式(不属于 GoF 23 种设计模式,是基础铺垫)
- 工厂方法模式(GoF 标准设计模式)
- 抽象工厂模式(GoF 标准设计模式)
二、1. 简单工厂模式
核心思想
定义一个工厂类,根据传入的参数,动态决定创建哪一种产品实例,产品需继承同一个父类或实现同一个接口。
适用场景
- 产品种类较少且相对固定,新增产品频率低。
- 客户端不需要关心产品创建细节,只需要传入指定参数。
无人售货柜项目案例:支付渠道创建
售货柜支持微信支付、支付宝两种渠道,用简单工厂统一创建支付对象。
步骤 1:定义产品接口
java
运行
// 支付渠道接口 public interface Payment { // 发起支付 void pay(BigDecimal amount); }步骤 2:实现具体产品
java
运行
// 微信支付实现 public class WechatPayment implements Payment { @Override public void pay(BigDecimal amount) { System.out.println("微信支付:" + amount + " 元"); } } // 支付宝支付实现 public class AlipayPayment implements Payment { @Override public void pay(BigDecimal amount) { System.out.println("支付宝支付:" + amount + " 元"); } }步骤 3:创建简单工厂类
java
运行
public class PaymentFactory { // 根据类型创建支付对象 public static Payment createPayment(String type) { if ("WECHAT".equals(type)) { return new WechatPayment(); } else if ("ALIPAY".equals(type)) { return new AlipayPayment(); } throw new IllegalArgumentException("不支持的支付类型"); } }步骤 4:客户端调用
java
运行
public class Client { public static void main(String[] args) { // 传入参数创建支付对象,无需关心具体实现 Payment wechatPay = PaymentFactory.createPayment("WECHAT"); wechatPay.pay(new BigDecimal("10.00")); Payment alipay = PaymentFactory.createPayment("ALIPAY"); alipay.pay(new BigDecimal("20.00")); } }优缺点
| 优点 | 缺点 |
|---|---|
| 客户端与产品解耦,只需知道参数即可创建对象 | 产品过多时,工厂类会变得臃肿(违反 “单一职责原则”) |
| 集中管理产品创建逻辑,便于维护 | 新增产品需要修改工厂类代码(违反 “开闭原则”) |
三、2. 工厂方法模式
核心思想
将简单工厂的工厂类抽象化,定义一个抽象工厂接口,由具体工厂子类负责创建对应的具体产品。
核心:一个产品对应一个工厂
适用场景
- 产品种类较多,且需要频繁新增产品。
- 客户端希望自主选择工厂创建产品,而非传入参数。
无人售货柜项目案例:IoT 设备连接工厂
售货柜有多种 IoT 设备(扫码枪、温控器、货道控制器),每种设备对应一个工厂。
步骤 1:定义产品接口
java
运行
// IoT 设备接口 public interface IoTdevice { // 建立连接 void connect(); }步骤 2:实现具体产品
java
运行
// 扫码枪设备 public class QrScanner implements IoTdevice { @Override public void connect() { System.out.println("扫码枪已连接到售货柜"); } } // 温控器设备 public class TemperatureController implements IoTdevice { @Override public void connect() { System.out.println("温控器已连接到售货柜"); } }步骤 3:定义抽象工厂接口
java
运行
// IoT 设备工厂接口 public interface IoTdeviceFactory { IoTdevice createDevice(); }步骤 4:实现具体工厂
java
运行
// 扫码枪工厂 public class QrScannerFactory implements IoTdeviceFactory { @Override public IoTdevice createDevice() { return new QrScanner(); } } // 温控器工厂 public class TemperatureControllerFactory implements IoTdeviceFactory { @Override public IoTdevice createDevice() { return new TemperatureController(); } }步骤 5:客户端调用
java
运行
public class Client { public static void main(String[] args) { // 创建扫码枪工厂 -> 生产扫码枪 IoTdeviceFactory scannerFactory = new QrScannerFactory(); IoTdevice scanner = scannerFactory.createDevice(); scanner.connect(); // 新增货道控制器时,只需加一个产品类 + 一个工厂类,无需修改原有代码 } }优缺点
| 优点 | 缺点 |
|---|---|
| 新增产品只需新增 “产品类 + 工厂类”,符合 “开闭原则” | 产品和工厂成对增加,类的数量会翻倍,增加系统复杂度 |
| 每个工厂只负责一种产品,符合 “单一职责原则” | 简单场景下会显得冗余 |
四、3. 抽象工厂模式
核心思想
创建一系列相关或相互依赖的产品族,而不指定具体类。
核心概念:
- 产品等级:同一类产品的不同实现(如微信支付、支付宝支付属于 “支付渠道” 等级)。
- 产品族:不同产品等级的组合,满足同一业务场景(如 “售货柜基础配置” 包含:扫码枪 + 温控器 + 货道控制器)。
适用场景
- 需要创建成套的产品组合,且产品族之间有依赖关系。
- 系统需要在多个产品族中切换,且不希望修改客户端代码。
无人售货柜项目案例:售货柜配置工厂
售货柜有两种配置:标准款(基础扫码枪 + 基础温控器)、高端款(智能扫码枪 + 精准温控器),每种配置是一个产品族。
步骤 1:定义多个产品等级接口
java
运行
// 扫码枪接口(产品等级 1) public interface QrScanner { void scan(); } // 温控器接口(产品等级 2) public interface TemperatureController { void adjustTemperature(); }步骤 2:实现具体产品(分产品族)
java
运行
// ========== 标准款产品族 ========== public class StandardQrScanner implements QrScanner { @Override public void scan() { System.out.println("标准款扫码枪:识别普通二维码"); } } public class StandardTemperatureController implements TemperatureController { @Override public void adjustTemperature() { System.out.println("标准款温控器:固定温度控制"); } } // ========== 高端款产品族 ========== public class PremiumQrScanner implements QrScanner { @Override public void scan() { System.out.println("高端款扫码枪:识别动态二维码 + 条形码"); } } public class PremiumTemperatureController implements TemperatureController { @Override public void adjustTemperature() { System.out.println("高端款温控器:智能调节温度(根据环境)"); } }步骤 3:定义抽象工厂接口(对应产品族)
java
运行
// 售货柜配置工厂接口(负责创建一个产品族) public interface VendingMachineFactory { QrScanner createQrScanner(); TemperatureController createTemperatureController(); }步骤 4:实现具体工厂(对应具体产品族)
java
运行
// 标准款配置工厂 public class StandardVendingMachineFactory implements VendingMachineFactory { @Override public QrScanner createQrScanner() { return new StandardQrScanner(); } @Override public TemperatureController createTemperatureController() { return new StandardTemperatureController(); } } // 高端款配置工厂 public class PremiumVendingMachineFactory implements VendingMachineFactory { @Override public QrScanner createQrScanner() { return new PremiumQrScanner(); } @Override public TemperatureController createTemperatureController() { return new PremiumTemperatureController(); } }步骤 5:客户端调用
java
运行
public class Client { public static void main(String[] args) { // 创建标准款售货柜配置 VendingMachineFactory standardFactory = new StandardVendingMachineFactory(); standardFactory.createQrScanner().scan(); standardFactory.createTemperatureController().adjustTemperature(); // 切换到高端款配置,客户端代码无需修改 VendingMachineFactory premiumFactory = new PremiumVendingMachineFactory(); premiumFactory.createQrScanner().scan(); premiumFactory.createTemperatureController().adjustTemperature(); } }优缺点
| 优点 | 缺点 |
|---|---|
| 支持产品族的整体切换,符合 “开闭原则” | 新增产品等级时,所有工厂类都需要修改,违反 “开闭原则” |
| 保证产品族内的产品兼容性 | 系统复杂度高,类的数量大幅增加 |
五、三种工厂模式对比
| 特性 | 简单工厂模式 | 工厂方法模式 | 抽象工厂模式 |
|---|---|---|---|
| 核心 | 一个工厂创建所有产品 | 一个产品对应一个工厂 | 一个工厂创建一个产品族 |
| 产品关系 | 同一产品等级 | 同一产品等级 | 多个产品等级(产品族) |
| 扩展性 | 差(新增产品需修改工厂) | 好(新增产品只需加工厂) | 产品族扩展好,产品等级扩展差 |
| 适用场景 | 产品少且固定 | 产品多且频繁新增 | 需要成套产品组合 |
六、工厂模式在无人售货柜项目中的落地建议
- 简单工厂:用于支付渠道、订单状态机等产品少的场景,减少冗余类。
- 工厂方法:用于IoT 设备实例化、多租户数据源创建,方便新增设备 / 租户类型。
- 抽象工厂:用于售货柜不同配置套餐(如基础款、旗舰款),支持整体配置切换。
- 结合 Spring 优化:可以将工厂类和产品类交给 Spring 容器管理,通过
@Autowired注入,避免手动new对象,进一步降低耦合。
七、工厂模式的核心设计原则
- 开闭原则:对扩展开放,对修改关闭(工厂方法、抽象工厂体现最佳)。
- 单一职责原则:每个工厂只负责创建对应的产品。
- 依赖倒置原则:客户端依赖抽象产品 / 工厂,而非具体实现。