Java设计模式中的策略模式(Strategy Patten)定义了一组算法,将每一个算法都封装起来,而且可以使它们之间能够相互替换,在客户端调用它们时能够互不影响。算法
策略模式主要由三个角色组成设计模式
一、抽象策略角色:一般是一个接口或抽象类实现,咱们的具体策略类就是继承或实现这个抽象角色。this
二、具体策略角色:咱们在这些类中写策略和算法,继承或实现抽象策略角色。spa
三、环境角色:环境角色中拥有一个抽象策略角色的引用,供客户端调用,该角色把客户端跟策略类的实现分离。设计
从上面的三个策略模式的角色中,咱们就大概能够知道策略模式的编写步骤,这里以实现简单的四则运算为例。code
一、定义抽象策略角色,也就是定义一个公共的抽象类(也能够是接口)对象
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 }
二、编写策略类,该类实现上面定义的抽象类blog
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 }
三、编写环境角色,其中持有一个抽象策略类的引用继承
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 }
四、编写客户端接口
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的使用是不太好的,简单工厂模式把生成策略类与客户端分离。
总结:
策略模式使开发人员可以开发出不少可替换的组件,而组件间是弱链接的,体现了代码的可重用行,弱链接也为之后开发新的组件打下了基础,具备较强的可扩展性,易于维护。策略模式是对算法的封装,它把算法的责任和算法自己分割开,委派给别的对象管理。客户端决定应该使用什么策略,所以客户端须要理解全部具体策略类之间的区别,这也增长了客户端的使用难度。