策略工厂模式详解(包含Java 实现)
·
目录
策略工厂模式 = 策略模式(Strategy) + 工厂模式(Factory),是开发中最常用的设计模式组合之一,专门解决:同一行为,多种实现,动态切换的场景(比如支付方式切换、优惠策略切换、文件解析方式切换)。
一、先搞懂两个基础模式
1. 策略模式
- 核心:定义一组算法(策略),分别封装,让它们可以互相替换。
- 解决:大量
if-else / switch判断不同实现逻辑的问题。 - 缺点:需要自己创建策略对象,还得自己管理用哪个策略。
2. 工厂模式
- 核心:专门负责创建对象,屏蔽创建细节。
- 解决:策略模式中手动
new对象、硬编码判断策略的问题。
3. 策略工厂模式(最终形态)
- 工厂负责:创建、管理所有策略(存到 Map 里,根据类型直接取)。
- 策略负责:自己的业务逻辑。
- 调用方:只需要传入类型,直接执行,无任何 if-else。
二、适用场景
你只要遇到下面这些情况,直接用策略工厂:
- 一个操作有多种实现方式(微信支付、支付宝、银行卡支付)。
- 需要动态切换算法 / 策略。
- 不想写一堆
if (type == 1) {...} else if (type == 2) {...}。 - 方便扩展新策略(加一个策略不用改旧代码,符合开闭原则)。
三、标准结构(5 个角色)
| 角色 | 作用 |
|---|---|
| Strategy 策略接口 | 定义所有策略必须实现的方法 |
| ConcreteStrategy 具体策略 | 实现接口,写各自的业务逻辑 |
| StrategyFactory 策略工厂 | 单例,管理所有策略,提供根据类型获取策略的方法 |
| StrategyContext 策略上下文(可选) | 封装调用,解耦调用方和策略 |
| Client 调用方 | 使用工厂获取策略,执行逻辑 |
四、Java 代码实现(完整可运行)
我们用支付场景举例:
- 策略:微信支付、支付宝支付、银行卡支付
- 工厂:统一管理这些支付策略
1. 定义策略接口(统一行为)
/**
* 支付策略接口
*/
public interface PaymentStrategy {
// 支付方法
void pay(double amount);
}
2. 实现具体策略(多种逻辑)
支付宝支付
public class AlipayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用支付宝支付:" + amount + " 元");
}
}
微信支付
public class WechatPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用微信支付:" + amount + " 元");
}
}
银行卡支付
public class BankCardPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用银行卡支付:" + amount + " 元");
}
}
3. 核心:策略工厂(关键!)
- 用 Map 存储所有策略(类型 -> 策略对象)
- 提供静态方法根据类型获取策略
- 天然消除
if-else
import java.util.HashMap;
import java.util.Map;
/**
* 支付策略工厂(单例)
*/
public class PaymentFactory {
// 1. 注册所有策略:key=支付类型,value=对应策略对象
private static final Map<String, PaymentStrategy> PAYMENT_MAP = new HashMap<>();
// 2. 静态代码块:项目启动时就把所有策略注册好
static {
PAYMENT_MAP.put("ALIPAY", new AlipayStrategy());
PAYMENT_MAP.put("WECHAT", new WechatPayStrategy());
PAYMENT_MAP.put("BANK_CARD", new BankCardPayStrategy());
}
// 3. 核心方法:根据类型获取策略(没有 if-else!)
public static PaymentStrategy getPayment(String type) {
if (type == null || !PAYMENT_MAP.containsKey(type)) {
throw new IllegalArgumentException("不支持的支付方式");
}
return PAYMENT_MAP.get(type);
}
}
4. (可选)策略上下文
封装调用,让代码更优雅:
/**
* 支付上下文:调用方直接用这个类
*/
public class PaymentContext {
private final PaymentStrategy strategy;
// 构造时从工厂获取策略
public PaymentContext(String type) {
this.strategy = PaymentFactory.getPayment(type);
}
// 执行支付
public void executePay(double amount) {
strategy.pay(amount);
}
}
5. 客户端调用(测试)
public class Client {
public static void main(String[] args) {
// 支付宝支付
PaymentContext context1 = new PaymentContext("ALIPAY");
context1.executePay(100);
// 微信支付
PaymentContext context2 = new PaymentContext("WECHAT");
context2.executePay(200);
// 银行卡支付
PaymentContext context3 = new PaymentContext("BANK_CARD");
context3.executePay(500);
}
}
运行结果
使用支付宝支付:100.0 元
使用微信支付:200.0 元
使用银行卡支付:500.0 元
五、如何扩展新策略?(体现优势)
假如现在要加云闪付,完全不用修改旧代码!
- 新增策略类:
public class UnionPayStrategy implements PaymentStrategy {
@Override
public void pay(double amount) {
System.out.println("使用云闪付支付:" + amount + " 元");
}
}
- 在工厂的
static块里加一行注册:
PAYMENT_MAP.put("UNION_PAY", new UnionPayStrategy());
- 直接调用:
new PaymentContext("UNION_PAY").executePay(300);
✅ 符合开闭原则:对扩展开放,对修改关闭
六、策略工厂模式的优点
- 消除大量 if-else:代码干净、可读性极高
- 易于扩展:加新策略只加类 + 注册,不改动旧代码
- 职责清晰:
- 策略:只管自己的逻辑
- 工厂:只管创建和管理
- 可动态切换:运行时根据类型自由换策略
- 符合设计原则:单一职责、开闭原则
七、和纯策略模式的区别
- 纯策略模式:你要自己
new AlipayStrategy()、自己判断类型 - 策略工厂模式:工厂帮你管理所有策略,你只传类型,直接用
八、进阶优化(企业级用法)
实际项目中,我们会用 注解 + 自动扫描 代替手动注册:
- 定义
@PayType("ALIPAY")注解 - 项目启动时自动扫描所有策略类
- 自动注册到工厂 Map
- 完全不用改工厂代码
总结
- 策略工厂 = 策略(做什么) + 工厂(怎么拿)
- 核心是 Map 存储策略 + 根据类型直接获取
- 解决:多实现、动态切换、消灭 if-else
- 扩展方便、代码优雅、企业最常用
更多推荐
所有评论(0)