Skip to content

策略

更新: 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());
    }
}

优缺点

优点:

  1. 算法可互换
  2. 消除条件语句
  3. 符合开闭原则
  4. 算法独立变化
  5. 提高代码复用
  6. 便于单元测试
  7. 支持组合策略

缺点:

  1. 策略类数量增加
  2. 客户端需了解策略差异
  3. 增加对象创建开销
  4. 策略间通信复杂
  5. 策略选择逻辑可能复杂
  6. 可能暴露实现细节

应用场景

  1. 多种支付方式
  2. 排序算法选择
  3. 数据压缩策略
  4. 表单验证规则
  5. 路由算法选择
  6. 机器学习模型选择
  7. 游戏 AI 行为策略
  8. 缓存淘汰策略

与其他模式的关系

  • 与状态模式:结构相似但目的不同(策略是算法选择,状态是行为随状态改变)
  • 与命令模式:策略是参数化对象
  • 与桥接模式:策略可看作桥接的简化版
  • 与工厂模式:工厂创建策略对象
  • 与模板方法模式:策略替代模板方法的子类
  • 与装饰器模式:策略改变内核行为,装饰器增加外围行为

JDK 中的策略模式

  1. Java Comparator 接口
  2. Java LayoutManager(布局管理器)
  3. Java ThreadPoolExecutor 拒绝策略
  4. Java 加密框架(Cipher)
  5. Java 压缩框架(Deflater)
  6. Java AWT RenderingHints
  7. Spring ResourceLoader 策略
  8. Java NIO 字符集编解码器

注意事项

  1. 策略生命周期管理
  2. 策略无状态设计
  3. 策略共享机制
  4. 策略选择算法
  5. 避免策略爆炸
  6. 策略组合技术
  7. 策略默认实现
  8. 策略与上下文解耦

贡献者

The avatar of contributor named as LI SIR LI SIR
The avatar of contributor named as wkwbk wkwbk

页面历史