1. 定义
策略模式定义了一系列的算法,并将每一个算法封装起来,使每个算法可以相互替代,使算法本身和使用算法的客户端分割开来,相互独立。
2. 结构
(1)策略接口角色IStrategy:用来约束一系列具体的策略算法,策略上下文角色使用此策略接口来调用具体的策略所实现的算法。
(2)具体的策略实现角色ConcreteStrategy:具体的策略实现。
(3)策略上下文角色StrategyContext:负责和具体的策略实现交互,通常策略上下文对象会持有一个真正的策略实现对象,策略上下文还可以让具体的策略实现从其中获取相关数据,回调策略上下文对象的方法。
3. 具体实现
(1)策略接口
public interface IStrategy {
public void testMethod();
}
(2) 具体的策略实现
public class ConcreteStrategy1 implements IStrategy {
@Override
public void testMethod() {
System.out.println("this is ConcreteStrategy1 method");
}
}
public class ConcreteStrategy2 implements IStrategy {
@Override
public void testMethod() {
System.out.println("this is ConcreteStrategy2 method");
}
}
(3)策略上下文
public class StrategyContext {
private IStrategy strategy;
public StrategyContext(IStrategy strategy) {
this.strategy = strategy;
}
public void contextMethod() {
strategy.testMethod();
}
}
(4) 外部客户端
public class Client {
public static void main (String[] args) {
//创建具体策略实现
IStrategy strategy = new ConcrategyStrategy2();
//在创建策略上下文的同时,将具体的策略实现对象注入到策略上下文中
StrategyContext ctx = new StrategyContext(strategy);
//调用策略上下文对象的方法来完成对具体策略实现的调用
ctx.contextStrategy();
}
}
策略模式的重点不是如何实现算法,而是如何组织和调用这些算法,从而让我们的程序结构更加灵活、可扩展。
策略模式就是把各个平等的具体实现进行抽象封装成独立的算法类,然后通过上下文和具体的算法类交互。各个策略算法都是平等的,所以它们可以互相替换,虽然可以动态切换各个算法,但是同一时刻只能使用一个策略。
我们上面的策略接口采用的是接口的形式来定义的, 其实这个策略接口,是广义上的接口,不是语言层面的interface,也可以是抽象类,如果对个算法具有共有的数据,则可以将策略接口设计成一个抽象类,把公共的东西放到抽象类里面去。
4. 策略模式的优点
(1)策略列都实现了同一个接口,因此策略类之间可以自由切换。
(2)易于扩展,增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有代码。
(3)避免过多使用多重条件语句(if else)
5. 策略模式的缺点
(1)客户端必须了解所有的策略,这暴露了策略的具体实现。
(2)增加了对象的数量,由于将每个算法都封装成一个策略类,如果可选的策略有很多的话,那对象的数量也会很多。
(3)只适合扁平的算法结构,各个策略实现的都是平等关系,限制了算法的使用层级,且不能被嵌套。
参考资料:https://www.cnblogs.com/lewis0077/p/5133812.html