Java设计模式中的策略模式(Strategy Patten)定义了一组算法,将每个算法都封装起来,并且可使它们之间可以相互替换,在客户端调用它们时可以互不影响。
策略模式主要由三个角色组成
1、抽象策略角色:通常是一个接口或抽象类实现,我们的具体策略类就是继承或实现这个抽象角色。
2、具体策略角色:我们在这些类中写策略和算法,继承或实现抽象策略角色。
3、环境角色:环境角色中拥有一个抽象策略角色的引用,供客户端调用,该角色把客户端跟策略类的实现分离。
从上面的三个策略模式的角色中,我们就大概可以知道策略模式的编写步骤,这里以实现简单的四则运算为例。
1、定义抽象策略角色,也就是定义一个公共的抽象类(也可以是接口)
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 *定义抽象策略角色
6 */
7 public abstract class Strategy {
8 //定义抽象策略的方法
9 public abstract int strategy(int a,int b);
10
11 }
2、编写策略类,该类实现上面定义的抽象类
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * AddStrategy
6 */
7 public class AddStrategy extends Strategy {
8 //定义实现加法的策略方法
9 public int strategy(int a, int b)
10 {
11 return a+b;
12 }
13
14 }
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * SubStrategy
6 */
7 public class SubStrategy extends Strategy {
8 //定义减法的策略方法
9 public int strategy(int a, int b)
10 {
11 return a-b;
12 }
13
14 }
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * MultiplyStrategy
6 */
7 public class MultiplyStrategy extends Strategy {
8 //定义乘法的策略方法
9 public int strategy(int a,int b)
10 {
11 return a*b;
12 }
13 }
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * DivStrategy
6 */
7 public class DivStrategy extends Strategy {
8 //定义除法的策略方法,这里为了简单就不考虑除数为零的情况了
9 public int strategy(int a,int b)
10 {
11 return a/b;
12 }
13 }
3、编写环境角色,其中持有一个抽象策略类的引用
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * Context
6 */
7 public class Context {
8 //持有抽象策略角色的引用,用于客户端调用
9 private Strategy strategy;
10 //获得策略类
11 public Strategy getStrategy() {
12 return strategy;
13 }
14 //设置所需策略
15 public void setStrategy(Strategy strategy) {
16 this.strategy = strategy;
17
18 }
19 //根据设置的策略类返回对应的结果
20 public int getResult(int a,int b)
21 {
22 return strategy.strategy(a, b);
23 }
24
25 }
4、编写客户端
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * Client
6 */
7 public class Client {
8 public static void main(String[] args) {
9
10 Context context = new Context();
11
12 int result;
13
14 context.setStrategy(new SubStrategy());
15
16 result = context.getResult(9, 3);
17
18 System.out.println("sub: "+result);
19
20 context.setStrategy(new AddStrategy());
21
22 result =context.getResult(9, 3);
23
24 System.out.println("add: "+result);
25
26 context.setStrategy(new DivStrategy());
27
28 result = context.getResult(9, 3);
29
30 System.out.println("div: "+result);
31
32 context.setStrategy(new MultiplyStrategy());
33
34 result = context.getResult(9, 3);
35
36 System.out.println("mul: "+result);
37 }
38 }
输出结果:
上面只是用到策略模式,下面加上简单工厂模式
工厂类
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * Factory
6 */
7 public class Factory {
8 public Strategy createStrategy(String str)
9 {
10 if("AddStrategy".equalsIgnoreCase(str))
11 {
12 return new AddStrategy();
13 }
14 else
15 if("SubStrategy".equalsIgnoreCase(str))
16 {
17 return new SubStrategy();
18 }
19 else
20 if("DivStrategy".equalsIgnoreCase(str))
21 {
22 return new DivStrategy();
23 }
24 else
25 if("MultiplyStrategy".equalsIgnoreCase(str))
26 {
27 return new MultiplyStrategy();
28 }
29 else
30 return null;
31 }
32
33 }
客户端类
1 package strategy;
2 /**
3 *
4 * @author CIACs
5 * Client
6 */
7 public class Client {
8 public static void main(String[] args) {
9
10 Context context = new Context();
11 int result;
12 Strategy strategy;
13 Factory fac = new Factory();
14 strategy = fac.createStrategy("AddStrategy");
15 context.setStrategy(strategy);
16 result = context.getResult(9, 3);
17 System.out.println(result);
18 }
19 }
输出结果:
当然这里的工厂类中的if-else的使用是不太好的,简单工厂模式把生成策略类与客户端分离。
总结:
策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给别的对象管理。客户端决定应该使用什么策略,因此客户端需要理解所有具体策略类之间的区别,这也增加了客户端的使用难度。