目录
[二、1. 简单工厂模式](#二、1. 简单工厂模式)
[步骤 1:定义产品接口](#步骤 1:定义产品接口)
[步骤 2:实现具体产品](#步骤 2:实现具体产品)
[步骤 3:创建简单工厂类](#步骤 3:创建简单工厂类)
[步骤 4:客户端调用](#步骤 4:客户端调用)
[三、2. 工厂方法模式](#三、2. 工厂方法模式)
[无人售货柜项目案例:IoT 设备连接工厂](#无人售货柜项目案例:IoT 设备连接工厂)
[步骤 1:定义产品接口](#步骤 1:定义产品接口)
[步骤 2:实现具体产品](#步骤 2:实现具体产品)
[步骤 3:定义抽象工厂接口](#步骤 3:定义抽象工厂接口)
[步骤 4:实现具体工厂](#步骤 4:实现具体工厂)
[步骤 5:客户端调用](#步骤 5:客户端调用)
[四、3. 抽象工厂模式](#四、3. 抽象工厂模式)
[步骤 1:定义多个产品等级接口](#步骤 1:定义多个产品等级接口)
[步骤 2:实现具体产品(分产品族)](#步骤 2:实现具体产品(分产品族))
[步骤 3:定义抽象工厂接口(对应产品族)](#步骤 3:定义抽象工厂接口(对应产品族))
[步骤 4:实现具体工厂(对应具体产品族)](#步骤 4:实现具体工厂(对应具体产品族))
[步骤 5:客户端调用](#步骤 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对象,进一步降低耦合。
七、工厂模式的核心设计原则
- 开闭原则:对扩展开放,对修改关闭(工厂方法、抽象工厂体现最佳)。
- 单一职责原则:每个工厂只负责创建对应的产品。
- 依赖倒置原则:客户端依赖抽象产品 / 工厂,而非具体实现。