本文参考:
在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。
在策略模式中主要两类对象,一类表示各种策略的对象及其统一接口,一类 context 对象。策略对象改变 context 对象的执行算法。
意图: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。
主要解决: 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。
应用实例: 1、诸葛亮的锦囊妙计,每一个锦囊就是一个策略。 2、旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。 3、ThreadPoolExecutor中的拒绝策略RejectedExecutionHandler
优点: 1、算法可以自由切换。 2、避免使用多重条件判断。 3、扩展性良好。
缺点: 1、策略类会增多。 2、所有策略类都需要对外暴露。
使用场景: 1、如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。 2、一个系统需要动态地在几种算法中选择一种。 3、如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。
实现:
实现一个多功能的计算类,可以提供加、减、乘运算。
我们将创建一个定义活动的 Strategy 接口和实现了 Strategy 接口的实体策略类。Context 是一个使用了某种策略的类。
Main方法在StrategyPatternDemo中,我们的演示类使用 Context 和策略对象来演示 Context 在它所配置或使用的策略改变时的行为变化。
- 定义Strategy接口
public interface Strategy {
int doOp(int a,int b);
}
- 创建实现了Strategy接口的各种实体策略类
public class AddStrategy implements Strategy{
@Override
public int doOp(int a, int b) {
return a+b;
}
}
public class MulStrategy implements Strategy{
@Override
public int doOp(int a, int b) {
return a*b;
}
}
public class SubStrategy implements Strategy{
@Override
public int doOp(int a, int b) {
return a-b;
}
}
- 实现策略模式的Context类,这里背后的知识是Java的多态,传入的策略都是基于Strategy接口实现的,编译都不会报错,运行doOp方法的时候,就看传入进去的实现子类的方法实现。
public class Context {
Strategy strategy;
public Context(Strategy strategy){
this.strategy=strategy;
}
public int doStrategy(int a,int b){
return strategy.doOp(a,b);
}
}
- 测试
public class StrategyDemo {
public static void main(String[] args) {
Context context1 = new Context(new AddStrategy()); // 加法
int result1 = context1.doStrategy(1,2);
System.out.println(result1);
Context context2 = new Context(new SubStrategy()); // 减法
int result2 = context2.doStrategy(1, 2);
System.out.println(result2);
Context context3 = new Context(new MulStrategy()); // 乘法
int result3= context3.doStrategy(1,2);
System.out.println(result3);
}
}
输出:
3
-1
2