定义
策略模式(Strategy Pattern)也叫政策模式,是一种比较简单的模式。
英文原话:Define a family of algorithms,encapsulate each one,and make them interchangeable.
翻译:定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以互相替换,使得算法可以在不影响客户端的情况下发生变化。
UML图
代码
角色:
环境(Context)角色:该角色也叫上下文角色,有承上启下的作用,屏蔽高层模块对策略、算法的直接访问,它持有一个Strategy类的引用。
抽象策略(Strategy)角色:该角色对策略、算法进行抽象,通常定义每个策略或算法必须具有的方法和属性。
具体策略(Concrete Strategy)角色:该角色实现抽象策略中的具体操作,含有具体的算法。
/** * 抽象策略类 */ public abstract class Strategy { //策略方法 public abstract void strategyInterface(); } /** * 具体策略类 */ public class ConcreteStrategy extends Strategy { //实现策略方法 @Override public void strategyInterface() { //具体算法 System.out.println("具体策略算法"); } } /** * 环境角色类 */ public class Context { private Strategy strategy = null; public Context(Strategy strategy) { this.strategy = strategy; } //调用策略方法 public void contextInterface(){ this.strategy.strategyInterface(); }
/**
* 测试方法
*/
public static void main(String[] args) {
Strategy strategy = new ConcreteStrategy(); //实例化一个策略类,此处可替换为其他策略
Context context = new Context(strategy); //环境类封装策略类
context.contextInterface(); //环境类调用方法
}
}
优点
- 策略模式提供了相关的算法族的办法。策略类的等级结构定义了一个算法或行为族,恰当地使用继承可以把公共的代码移到父类中,从而避免代码重复。
- 策略模式提供了可以替换继承关系的办法。继承可以处理多种算法或行为,如果不用策略模式,那么使用算法或行为的环境类就可能会有一些子类,每一个子类提供一个不同的算法或行为。但是,这样算法或行为的使用者就和算法本身混合在一起,从而不可能再独立演化。
- 使用策略模式可以避免使用多重条件转移语句。多重条件转移语句不易维护,它把采取哪一种算法或采取哪一种行为的逻辑与算法的逻辑混合在一起,统统列在一个多重条件转移语句里面,这比使用继承办法还要原始和落后。
缺点
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。即策略模式只适用于客户端知道所有的算法或行为的情况。
- 策略模式造成很多的策略类。有时候可以通过把依赖于环境的状态保持到客户端里面,同时将策略类设计成可共享的,这样策略类实例就可以被不同客户端使用。可以使用享元模式来减少对象的数量。
应用场景
- 多个类只是在算法或行为上稍有不同的场景。
- 算法需要自由切换的场景。
- 需要屏蔽算法规则的场景。