策略
更新: 6/22/2025 字数: 0 字 时长: 0 分钟
定义
策略模式 (Strategy Pattern) 定义了一系列算法,并将每个算法封装起来,使它们可以相互替换。该模式让算法的变化独立于使用算法的客户,实现了算法的解耦和扩展。
角色
- 上下文 (Context):维护策略引用,调用具体策略
- 抽象策略 (Strategy):定义算法接口
- 具体策略 (ConcreteStrategy):实现具体算法
- 客户端 (Client):创建上下文并设置策略
实现
支付系统
java
// 支付策略接口
public interface PaymentStrategy {
void pay(double amount);
}
// 信用卡支付
public class CreditCardPayment implements PaymentStrategy {
private String cardNumber;
private String cvv;
public CreditCardPayment(String cardNumber, String cvv) {
this.cardNumber = cardNumber;
this.cvv = cvv;
}
@Override
public void pay(double amount) {
System.out.printf("使用信用卡支付 %.2f 元 (卡号:%s)%n", amount, maskCardNumber(cardNumber));
// 实际支付逻辑...
}
private String maskCardNumber(String cardNumber) {
return "****-****-****-" + cardNumber.substring(cardNumber.length() - 4);
}
}
// 支付宝支付
public class AlipayPayment implements PaymentStrategy {
private String account;
public AlipayPayment(String account) {
this.account = account;
}
@Override
public void pay(double amount) {
System.out.printf("使用支付宝支付 %.2f 元 (账号:%s)%n", amount, account);
// 实际支付逻辑...
}
}
// 微信支付
public class WechatPayment implements PaymentStrategy {
private String openId;
public WechatPayment(String openId) {
this.openId = openId;
}
@Override
public void pay(double amount) {
System.out.printf("使用微信支付 %.2f 元 (OpenID: %s)%n", amount, openId);
// 实际支付逻辑...
}
}
// 支付上下文
public class PaymentContext {
private PaymentStrategy strategy;
public void setStrategy(PaymentStrategy strategy) {
this.strategy = strategy;
}
public void executePayment(double amount) {
if (strategy == null) {
throw new IllegalStateException("未设置支付策略");
}
strategy.pay(amount);
}
}
// 使用示例
public class PaymentDemo {
public static void main(String[] args) {
PaymentContext context = new PaymentContext();
// 使用信用卡支付
context.setStrategy(new CreditCardPayment("1234567890123456", "123"));
context.executePayment(100.0);
// 切换为支付宝支付
context.setStrategy(new AlipayPayment("[email protected]"));
context.executePayment(200.0);
// 切换为微信支付
context.setStrategy(new WechatPayment("o6_bmjrPTlm6_2sgVt7hMZOPfL2M"));
context.executePayment(150.0);
}
}
排序算法
java
// 排序策略接口
public interface SortStrategy {
void sort(int[] array);
}
// 冒泡排序
public class BubbleSort implements SortStrategy {
@Override
public void sort(int[] array) {
System.out.println("使用冒泡排序");
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (array[j] > array[j + 1]) {
int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
}
}
// 快速排序
public class QuickSort implements SortStrategy {
@Override
public void sort(int[] array) {
System.out.println("使用快速排序");
quickSort(array, 0, array.length - 1);
}
private void quickSort(int[] array, int low, int high) {
if (low < high) {
int pivot = partition(array, low, high);
quickSort(array, low, pivot - 1);
quickSort(array, pivot + 1, high);
}
}
private int partition(int[] array, int low, int high) {
int pivot = array[high];
int i = low - 1;
for (int j = low; j < high; j++) {
if (array[j] < pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int temp = array[i + 1];
array[i + 1] = array[high];
array[high] = temp;
return i + 1;
}
}
// 归并排序
public class MergeSort implements SortStrategy {
@Override
public void sort(int[] array) {
System.out.println("使用归并排序");
mergeSort(array, 0, array.length - 1);
}
private void mergeSort(int[] array, int left, int right) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(array, left, mid);
mergeSort(array, mid + 1, right);
merge(array, left, mid, right);
}
}
private void merge(int[] array, int left, int mid, int right) {
int[] temp = new int[right - left + 1];
int i = left, j = mid + 1, k = 0;
while (i <= mid && j <= right) {
if (array[i] <= array[j]) {
temp[k++] = array[i++];
} else {
temp[k++] = array[j++];
}
}
while (i <= mid) temp[k++] = array[i++];
while (j <= right) temp[k++] = array[j++];
System.arraycopy(temp, 0, array, left, temp.length);
}
}
// 排序上下文
public class SortContext {
private SortStrategy strategy;
public void setStrategy(SortStrategy strategy) {
this.strategy = strategy;
}
public void executeSort(int[] array) {
System.out.println("排序前:" + Arrays.toString(array));
strategy.sort(array);
System.out.println("排序后:" + Arrays.toString(array));
}
}
// 使用示例
public class SortDemo {
public static void main(String[] args) {
SortContext context = new SortContext();
int[] data = {5, 2, 9, 1, 5, 6};
// 使用冒泡排序
context.setStrategy(new BubbleSort());
context.executeSort(data.clone());
// 使用快速排序
context.setStrategy(new QuickSort());
context.executeSort(data.clone());
// 使用归并排序
context.setStrategy(new MergeSort());
context.executeSort(data.clone());
}
}
优缺点
优点:
- 算法可互换
- 消除条件语句
- 符合开闭原则
- 算法独立变化
- 提高代码复用
- 便于单元测试
- 支持组合策略
缺点:
- 策略类数量增加
- 客户端需了解策略差异
- 增加对象创建开销
- 策略间通信复杂
- 策略选择逻辑可能复杂
- 可能暴露实现细节
应用场景
- 多种支付方式
- 排序算法选择
- 数据压缩策略
- 表单验证规则
- 路由算法选择
- 机器学习模型选择
- 游戏 AI 行为策略
- 缓存淘汰策略
与其他模式的关系
- 与状态模式:结构相似但目的不同(策略是算法选择,状态是行为随状态改变)
- 与命令模式:策略是参数化对象
- 与桥接模式:策略可看作桥接的简化版
- 与工厂模式:工厂创建策略对象
- 与模板方法模式:策略替代模板方法的子类
- 与装饰器模式:策略改变内核行为,装饰器增加外围行为
JDK 中的策略模式
- Java Comparator 接口
- Java LayoutManager(布局管理器)
- Java ThreadPoolExecutor 拒绝策略
- Java 加密框架(Cipher)
- Java 压缩框架(Deflater)
- Java AWT RenderingHints
- Spring ResourceLoader 策略
- Java NIO 字符集编解码器
注意事项
- 策略生命周期管理
- 策略无状态设计
- 策略共享机制
- 策略选择算法
- 避免策略爆炸
- 策略组合技术
- 策略默认实现
- 策略与上下文解耦