1 模式介绍
我们在写代码的时候经常会遇到很多选择,需要使用if-else或者switch-case来完成选择,如果业务逻辑简单,还是比较容易处理的,但是业务逻辑复杂,我们写在一起就会使代码变得臃肿,不易维护,这就违反了六大基本原则中的开放封闭原则和单一职责原则了。而策略模式就可以很好的解决这些问题,
2 模式定义
策略模式定义了一系列的算法,并将每个算法封装起来,而且使它们之间可以替换。策略模式让算法独立于使用它的客户而独立变化。
3 策略模式的UML类图
角色介绍:
- Context:上下文角色,用来操作策略的上下文;
- Stragety: 抽象策略角色,对算法、策略的抽象;
- ConcreteStragety:具体的策略实现。
4 模式使用示例
下面通过一个选择交通工具的案例来实现策略模式
抽象策略类
/**
* Description: 抽象策略类
*/
public interface TakeStrategy {
void take();
}
首先定义一个接口,take乘坐方式的方法
具体策略的实现,一个乘坐公交车,一个开车
/**
* Description: 具体策略的实现
*/
public class BusStrategy implements TakeStrategy {
@Override
public void take() {
System.out.println("乘坐公交车");
}
}
/**
* Description: 具体策略的实现
*/
public class CarStrategy implements TakeStrategy{
@Override
public void take() {
System.out.println("自己开车");
}
}
上下文角色 其中构造方法包含了策略类,通过不同的具体策略,来调用不同的体策略的方法
/**
* Created by Monkey on 2020/5/24.
* Description: 上下文角色, 通过不同的具体策略,来调用不同的体策略的方法
*/
public class Context {
private TakeStrategy takeStrategy;
private Context(TakeStrategy takeStrategy) {
this.takeStrategy = takeStrategy;
}
private void take(){
takeStrategy.take();
}
}
客户端
public static void main(String[] args) {
Context content;
content = new Context(new BusStrategy());
content.take();
content = new Context(new CarStrategy());
content.take();
}
在这里我们只需要传一个具体的策略就可以了,不需要关心具体策略里面是怎么实现的。结构也很清晰,使用也简单。
5 总结
使用场景:
- 针对同一类型问题的多种处理方式,仅仅是具体行为有差别时;
- 需要安全地封装多种同一类型的操作时;
- 出现同一抽象类有多个子类,而又需要使用if-else或者switch-case来选择具体子类。
优点:
- 结构清晰,使用简单
- 可以避免使用多重条件语句,易于维护;
- 易于扩展,需要添加一个策略时,只需要实现接口就可以看。
缺点:
- 每一个策略都是一个类,复用性小,策略过多时,类也随之增加。