策略模式
策略模式又叫政策模式(Policy Pattern),它是将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。可以避免多重分支的if……else和switch语句。
主要角色
策略模式的主要角色如下:
- 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
- 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
- 环境(Context)类:持有一个策略类的引用,最终给客户端调用。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class Compute(){ public int compute(int a,int b,char s){ if(s.equals('+')){ return a+b; }else if(s.equals('-')){ return a-b; }else if(s.equals('*')){ return a*b; }else if(s.equals('/')){ return a/b; } } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
| public interface ComputeStrategy{ public int compute(int a,int b); }
public class Add implements ComputeStrategy { public int compute(int a,int b){ return a+b; } }
public class Sub implements ComputeStrategy { public int compute(int a,int b){ return a-b; } }
public class Mul implements ComputeStrategy{ public int compute(int a,int b){ return a*b; } }
public class Div implements ComputeStrategy{ public int compute(int a,int b){ return a/b; } }
public class ComputeContext { private ComputeStrategy strategy;
public ComputeContext(ComputeStrategy strategy) { this.strategy = strategy; }
public int executeStrategy(int num1, int num2) { return strategy.compute(num1, num2); } }
public static void main(String[] args) { int a=8,b=2; ComputeContext context = new ComputeContext(new Add()); System.out.println("a + b = "+context.executeStrategy(a, b)); ComputeContext context2 = new ComputeContext(new Sub()); System.out.println("a - b = "+context2.executeStrategy(a, b)); ComputeContext context3 = new ComputeContext(new Mul()); System.out.println("a * b = "+context3.executeStrategy(a, b)); ComputeContext context4 = new ComputeContext(new Div()); System.out.println("a / b = "+context4.executeStrategy(a, b)); }
|
总结
适用场景:
- 系统中有很多类,而它们的区别仅仅在于它们的行为不同。
- 系统需要动态地在几种算法中选择一种。
- 需要屏蔽算法规则。
优点:
- 符合开闭原则。
- 避免使用多重条件语句。
- 可以提高算法的保密性和安全性。
- 易于扩展。
缺点:
- 客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
- 代码中会产生非常多的策略类,增加维护难度。