1. 定义
策略模式(Strategy Pattern):定义一系列算法,将每一个算法封装起来,并让它们可以相互替换,让算法独立于使用它的客户而变化。
2. 作用
策略模式是对算法的封装,它把算法的责任和算法本身分离,委派给不同的对象管理。策略模式通常把算法封装到一系列的策略类里面,作为抽象策略类的子类。用一句话来说,就是「准备一组算法,并将每个算法封装起来,使得它们可以互换」。策略模式并不决定在何时使用何种算法,算法的选择由客户端来决定。
3. 角色
- 上下文:对策略进行二次封装,目的是避免高层模块对策略的直接调用。
- 抽象策略:通常情况下是一个接口,当各个实现类中存在着重复的逻辑时,则使用抽象类来封装这部分公共的代码,此时,策略模式看上去更像是模版方法模式。
- 具体策略:具体策略角色通常由一组封装了算法的类来担任,这些类之间可以根据需要自由替换。
4. 实现
就拿出行方式来举个例子,我们去上班的方式有许多,可以开车、坐公交、骑车等。那么就可以把出行方式抽象出一个策略接口,各种具体的方式是策略实现,在出门时就可以自由选择啦。
类图- 定义抽象策略,就是出行方式。
public interface IOutWay {
/**
* 外出方式
*/
void goOut();
}
- 定义具体策略,可以是汽车、公交出行。
public class CarWay implements IOutWay {
@Override
public void goOut() {
System.out.println("开汽车");
}
}
public class BusWay implements IOutWay {
@Override
public void goOut() {
System.out.println("做公交车");
}
}
- 定义上下文,封装出行方式,调用其出行方法。
public class OutContext {
private IOutWay outWay;
public OutContext(IOutWay outWay) {
this.outWay = outWay;
}
public void setOutWay(IOutWay outWay) {
this.outWay = outWay;
}
public void go2Work() {
outWay.goOut();
}
}
- 测试。
public class StrategyTest {
public static void main(String[] args) {
OutContext outContext = new OutContext(new CarWay());
outContext.go2Work();
outContext.setOutWay(new BusWay());
outContext.go2Work();
}
}
5. 优缺点
1. 优点:
易于扩展,对「开闭原则」完美支持,在不修改原有系统的基础上,可以更换算法或者增加新的算法,提高了代码的复用性,是一种替换继承,避免多重条件转移语句的实现方式。
2. 缺点:
客户端必须知道所有的策略类,并理解其区别,同时在一定程度上增加了系统中类的个数,可能会存在很多策略类。
3. 使用场景:
在一个系统里面有许多类,它们之间的区别仅在于它们的行为,使用策略模式可以动态地让一个对象在许多行为中选择一种行为;一个系统需要动态地在几种算法中选择一种;避免使用难以维护的多重条件选择语句。
参考文章:
网友评论