介绍
当我们有一组算法需要进行切换的时候可以采用策略模式。
类图关系
context:封装角色
它也叫上下文角色,起承上启下的封装作用,屏蔽高层模块对策略,算法的直接访问
Strategy:抽象策略角色
策略,算法家族的抽象,通常为接口,定义每个策略或算法必须具有的算法和属性。
ConcreteStratedy:具体策略角色
实现抽象策略中的操作,该类含有具体的算法
示例代码
抽象策略类
interface Strategy{ //策略模式的运算法则 public void doSomething(); }
具体策略类1
class ContreteStrategy1 implements Strategy{ @Override public void doSomething(){ System.out.println("具体策划类1的运算法则"); } }
具体策略类2
class ConcreteStragegy2 implements Strategy{ @Override public void doSomething() { System.out.println("具体策略2的运算法则"); } }
上下文类
class Context{ // 抽象策略 private Strategy strategy = null; //构造函数设置具体策略 public Context(Strategy _strategy){ this.strategy = _strategy; } //封装后的策略方法 public void doAnything(){ this.strategy.doSomething(); } }
场景类
class Client{ public static void main(String[] args) { String str = "策略1"; Context context; //声明一个具体的策略 Strategy strategy1 = new ContreteStrategy1(); Strategy strategy2 = new ConcreteStragegy2(); //声明上下文对象 if(str.equals("策略1")) context = new Context(strategy1); else context = new Context(strategy2); context.doAnything(); } }
场景类中根据不同情况选择不同的策略,最后执行策略类的方法。
总结
优点:算法可以自由切换,避免使用多重条件判断,扩展性良好
缺点:策略数量增多,所有的策略类向外暴露,违背迪米特法则
扩展
为了防止策略类扩展,可以使用枚举类处理
public enum Strategy{ ADD("+"){ public int exec(int a, int b){ return a+b; } }, SUB("-"){ public int exec(int a, int b){ return a-b; } }; Strategy(String _value){ this.value = _value; } public String getValue(){ return this.value; } public abstract int exec(int a, int b); }