文章目录
一、策略模式的定义
策略模式(Strategy Pattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装起来,使它们可以互相替换。策略模式让算法的变化独立于使用算法的客户端,从而实现算法的灵活切换。
正如所述:"策略模式是指有一定行动内容的相对稳定的策略名称。"在软件开发中,它通过"将算法的实现与算法的使用分离",使算法可以独立于使用它的客户端而变化。
二、策略模式的核心组成
策略模式包含三个核心角色:
-
抽象策略角色(Strategy):
- 由一个接口或者抽象类实现
- 定义所有支持的算法的公共接口
-
具体策略角色(ConcreteStrategy):
- 包装了相关的算法和行为
- 实现抽象策略接口,提供具体的算法实现
-
环境角色(Context):
- 持有一个策略类的引用
- 负责与客户端交互,将具体的算法执行委托给策略对象
三、策略模式的工作原理
策略模式的核心思想是将算法的定义与使用分离,通过面向接口编程,使客户端可以在运行时根据需要选择不同的算法。
具体工作流程:
- 定义抽象策略接口,声明所有具体策略都需要实现的方法
- 实现多个具体策略类,每个类对应一种具体的算法
- 环境类中维护一个抽象策略的引用,提供方法用于设置具体策略
- 客户端创建具体策略对象,通过环境类的方法设置策略
- 环境类在需要时调用策略对象的方法,执行具体算法
四、策略模式的优点
- 避免使用多重条件语句:用多态替代if-else或switch-case,使代码更清晰
- 遵循开闭原则:新增策略只需实现接口,无需修改原有代码
- 提高代码复用性:每个策略都是独立的类,便于复用和测试
- 动态切换算法:可以在运行时根据需要切换不同的策略
- 算法的独立性:算法可以独立于客户端变化而变化,提供算法的可扩展性
五、策略模式的缺点
- 客户端必须知道所有策略:客户端需要知道所有的策略,并且自行决定使用哪一个策略
- 增加对象数量:每一个具体策略都是一个类,会增加类的数量
- 策略类增多:如果策略种类太多,会导致类数量过多,增加维护难度
六、策略模式的应用场景
- 需要使用多个变体的算法:系统需要在运行时动态地选择算法的场景
- 算法的使用频繁变化:需要频繁更改或扩展算法的场景
- 消除条件语句:需要用策略模式来替代复杂的条件分支语句的场景
- 多类只区别在表现行为不同:多个类只区别在表现行为不同,可以使用Strategy模式
七、策略模式的典型应用场景
- 支付方式选择:支付宝、微信、银联等不同支付策略
- 排序算法:冒泡排序、快速排序、归并排序等可互换
- 导航算法:步行导航、驾车导航、公共交通导航等
- 折扣计算:普通折扣、会员折扣、满减折扣等
- 邮件发送策略:SMTP、IMAP、POP3等不同邮件发送方式
八、策略模式的Java实现示例
java
// 1. 抽象策略接口:定义计算操作
interface CalculationStrategy {
int execute(int a, int b);
}
// 2. 具体策略:加法
class AdditionStrategy implements CalculationStrategy {
@Override
public int execute(int a, int b) {
return a + b;
}
}
// 3. 具体策略:减法
class SubtractionStrategy implements CalculationStrategy {
@Override
public int execute(int a, int b) {
return a - b;
}
}
// 4. 具体策略:乘法
class MultiplicationStrategy implements CalculationStrategy {
@Override
public int execute(int a, int b) {
return a * b;
}
}
// 5. 环境类:计算器
class Calculator {
private CalculationStrategy strategy;
public void setStrategy(CalculationStrategy strategy) {
this.strategy = strategy;
}
public int calculate(int a, int b) {
if (strategy == null) {
throw new IllegalStateException("策略未设置");
}
return strategy.execute(a, b);
}
}
// 6. 客户端使用
public class StrategyPatternDemo {
public static void main(String[] args) {
Calculator calculator = new Calculator();
// 使用加法策略
calculator.setStrategy(new AdditionStrategy());
System.out.println("10 + 5 = " + calculator.calculate(10, 5));
// 使用减法策略
calculator.setStrategy(new SubtractionStrategy());
System.out.println("10 - 5 = " + calculator.calculate(10, 5));
// 使用乘法策略
calculator.setStrategy(new MultiplicationStrategy());
System.out.println("10 * 5 = " + calculator.calculate(10, 5));
}
}
九、策略模式的优化:策略工厂
当策略类较多时,可以使用策略工厂来简化客户端的使用:
java
// 策略工厂类
public class StrategyFactory {
private static final Map<String, CalculationStrategy> strategies = new HashMap<>();
static {
strategies.put("add", new AdditionStrategy());
strategies.put("subtract", new SubtractionStrategy());
strategies.put("multiply", new MultiplicationStrategy());
}
public static CalculationStrategy getStrategy(String type) {
if (type == null || type.isEmpty()) {
throw new IllegalArgumentException("type should not be empty");
}
return strategies.get(type);
}
}
十、总结
-
策略模式是软件设计中非常实用的设计模式,它通过将算法封装为独立的类,使系统更加灵活、可扩展。它解决了"多重条件语句"的代码坏味道,使代码更加清晰易读。
-
正如所述:"策略模式作为一种软件设计模式,指对象有某个行为,但是在不同的场景中,该行为有不同的实现算法。"通过策略模式,我们可以在不修改客户端代码的情况下,动态地选择和切换算法,使系统更加符合开闭原则。
-
在实际开发中,策略模式是处理"算法族"问题的首选模式,尤其适用于需要在运行时动态选择算法的场景。