策略模式

策略模式又叫政策模式(Policy Pattern),它是将定义的算法家族分别封装起来,让它们之间可以互相替换,从而让算法的变化不会影响到使用算法的用户。可以避免多重分支的if……else和switch语句。

主要角色

策略模式的主要角色如下:

  • 抽象策略(Strategy)类:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现或行为。
  • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

代码

  • 不使用用设计模式代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 这里主要是简单的举个例子 因为策略模式主要是为了减少if else语句
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;
}
}
// 环境角色 主要是整合具体策略,供客户端调用
// 环境角色可以有很多种实现方式,也可以结合静态简单工厂和单例,也可以存入map中避免if else 具体如何选择取决于自己觉得合适的。
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));
}

总结

适用场景:

  • 系统中有很多类,而它们的区别仅仅在于它们的行为不同。
  • 系统需要动态地在几种算法中选择一种。
  • 需要屏蔽算法规则。

优点:

  • 符合开闭原则。
  • 避免使用多重条件语句。
  • 可以提高算法的保密性和安全性。
  • 易于扩展。

缺点:

  • 客户端必须知道所有的策略,并且自行决定使用哪一个策略类。
  • 代码中会产生非常多的策略类,增加维护难度。