策略模式 (Strategy Pattern)
什么是策略模式?
策略模式是一种行为型设计模式,它允许你定义一系列算法,把它们一个个封装起来,并且使它们可以相互替换。
简单来说:策略模式就是"多选一",根据不同情况选择不同的算法。
生活中的例子
想象一下:
- 出行方式:走路、骑车、开车、坐公交
- 支付方式:现金、微信、支付宝、银行卡
- 排序算法:冒泡排序、快速排序、归并排序
为什么需要策略模式?
传统方式的问题
// 使用if-else处理if(type=="走路"){walk();}elseif(type=="骑车"){ride();}elseif(type=="开车"){drive();}问题:
- 代码臃肿:大量if-else导致代码臃肿
- 难以扩展:新增算法需要修改代码
- 难以维护:算法逻辑分散在代码各处
策略模式的优势
// 使用策略模式Strategystrategy=newConcreteStrategyA();strategy.execute();优势:
- 算法分离:每个算法独立封装
- 易于扩展:新增算法很容易
- 易于维护:算法逻辑集中管理
- 运行时切换:可以在运行时切换算法
策略模式的结构
┌─────────────────────┐ │ Strategy │ 策略接口 ├─────────────────────┤ │ + execute(): void │ └──────────┬──────────┘ │ 实现 ├──┬──────────────────┬──────────────┐ │ │ │ ┌──────────┴──────┐ ┌───────────┴───────┐ ┌───┴────────┐ │ ConcreteStratA │ │ ConcreteStratB │ │ ... │ 具体策略 ├─────────────────┤ ├───────────────────┤ ├────────────┤ │ + execute() │ │ + execute() │ │ │ └─────────────────┘ └───────────────────┘ └────────────┘ ┌─────────────────────┐ │ Context │ 上下文 ├─────────────────────┤ │ - strategy: Strategy│ │ + setStrategy(): │ │ void │ │ + executeStrategy() │ │ : void │ └─────────────────────┘代码示例
1. 定义策略接口
/** * 策略接口 */publicinterfaceStrategy{/** * 执行策略 */voidexecute();}2. 定义具体策略
/** * 具体策略:走路 */publicclassWalkStrategyimplementsStrategy{@Overridepublicvoidexecute(){System.out.println("选择走路出行,健康环保");}}/** * 具体策略:骑车 */publicclassRideStrategyimplementsStrategy{@Overridepublicvoidexecute(){System.out.println("选择骑车出行,快速便捷");}}/** * 具体策略:开车 */publicclassDriveStrategyimplementsStrategy{@Overridepublicvoidexecute(){System.out.println("选择开车出行,舒适方便");}}/** * 具体策略:坐公交 */publicclassBusStrategyimplementsStrategy{@Overridepublicvoidexecute(){System.out.println("选择坐公交出行,经济实惠");}}3. 定义上下文
/** * 上下文:出行方式 */publicclassTravelContext{privateStrategystrategy;publicTravelContext(Strategystrategy){this.strategy=strategy;}publicvoidsetStrategy(Strategystrategy){this.strategy=strategy;}publicvoidexecuteStrategy(){strategy.execute();}}4. 使用策略
/** * 策略模式测试类 * 演示如何使用策略模式选择不同的出行方式 */publicclassStrategyTest{publicstaticvoidmain(String[]args){System.out.println("=== 策略模式测试 ===\n");// 创建上下文TravelContextcontext=newTravelContext(newWalkStrategy());// 测试不同的策略System.out.println("--- 走路 ---");context.executeStrategy();System.out.println("\n--- 骑车 ---");context.setStrategy(newRideStrategy());context.executeStrategy();System.out.println("\n--- 开车 ---");context.setStrategy(newDriveStrategy());context.executeStrategy();System.out.println("\n--- 坐公交 ---");context.setStrategy(newBusStrategy());context.executeStrategy();System.out.println("\n=== 策略模式的优势 ===");System.out.println("1. 算法分离:每个算法独立封装");System.out.println("2. 易于扩展:新增算法很容易");System.out.println("3. 易于维护:算法逻辑集中管理");System.out.println("4. 运行时切换:可以在运行时切换算法");System.out.println("5. 避免条件语句:避免大量if-else");System.out.println("\n=== 实际应用场景 ===");System.out.println("1. 排序算法:不同的排序算法");System.out.println("2. 支付方式:不同的支付方式");System.out.println("3. 出行方式:不同的出行方式");System.out.println("4. 压缩算法:不同的压缩算法");System.out.println("5. 路由算法:不同的路由算法");System.out.println("\n=== 与状态模式的区别 ===");System.out.println("策略模式:对象在不同策略下有不同的行为");System.out.println("状态模式:对象在不同状态下有不同的行为");System.out.println("策略模式:策略之间没有转换关系");System.out.println("状态模式:状态之间有转换关系");}}策略模式的优点
- 算法分离:每个算法独立封装
- 易于扩展:新增算法很容易
- 易于维护:算法逻辑集中管理
- 运行时切换:可以在运行时切换算法
- 避免条件语句:避免大量if-else
策略模式的缺点
- 类数量增加:每个策略都需要一个类
- 客户端复杂:客户端需要知道所有策略
适用场景
- 多个算法:有多个算法可以解决同一个问题
- 算法可替换:算法可以相互替换
- 运行时选择:需要在运行时选择算法
常见应用场景
- 排序算法:不同的排序算法
- 支付方式:不同的支付方式
- 出行方式:不同的出行方式
使用建议
- 多个算法:使用策略模式
- 算法可替换:使用策略模式
- 单一算法:直接调用即可
注意事项
⚠️ 策略模式虽然强大,但要注意:
- 不要让策略过多,增加复杂度
- 考虑使用工厂模式创建策略