策略模式
什么是策略模式
策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化
策略模式是对算法的包装,是把使用算法的责任和算法本身分开。策略模式通常是把一系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类。
例如下象棋时,炮的前进策略和马、兵的策略是不一样的,算法是有区别的。
我们开始实战,为了说明问题,我们以上图为例做一个超级简单的象棋(简单到没法玩象棋,嘿嘿),假设现在象棋只有炮、兵、将,代码如下。
1 public class Chess { 2 3 /** 4 * 兵前进算法 5 * @param a 原位 6 * @param b 目标为 7 */ 8 public void soldierGoAhead(int a, int b){ 9 System.out.println("兵"+a+"进"+b); 10 } 11 12 /** 13 * 炮前进算法 14 * @param a 原位 15 * @param b 目标为 16 */ 17 public void gunGoAhead(int a, int b){ 18 System.out.println("炮"+a+"进"+b); 19 } 20 }
这样写可以吗?如果随着我们的算法不断增加,如马的行走规则,象的行走规则等等,那么这个象棋类就得不断的改,那岂不是在作死。
我们开始用策略模式来改写代码。
抽象的策略接口:
1 public interface Strategy { 2 3 /** 4 * 前进策略 5 * @param a 原位 6 * @param b 目标位 7 */ 8 public void goAhead(int a, int b); 9 10 /** 11 * 平策略 12 * @param a 原位 13 * @param b 目标位 14 */ 15 public void straight(int a, int b); 16 }
实现炮的行走策略:
1 public class GunStrategy implements Strategy { 2 3 /** 4 * 炮前进策略 5 * @param a 原位 6 * @param b 目标位 7 */ 8 @Override 9 public void goAhead(int a, int b) { 10 System.out.println("炮"+a+"进"+b); 11 } 12 13 /** 14 * 炮平策略 15 * @param a 原位 16 * @param b 目标位 17 */ 18 @Override 19 public void straight(int a, int b) { 20 System.out.println("炮"+a+"平"+b); 21 } 22 }
实现兵的行走策略:
1 public class SoldierStrategy implements Strategy { 2 3 /** 4 * 兵进策略 5 * @param a 原位 6 * @param b 目标位 7 */ 8 @Override 9 public void goAhead(int a, int b) { 10 if(b-a==1){ 11 System.out.println("兵"+a+"进"+b); 12 }else { 13 System.out.println("我是兵,我只能前进不能后退。"); 14 } 15 } 16 17 /** 18 * 兵平策略 19 * @param a 原位 20 * @param b 目标位 21 */ 22 @Override 23 public void straight(int a, int b) { 24 if(b-a==1){ 25 System.out.println("兵"+a+"平"+b); 26 }else { 27 System.out.println("我是兵,我只能平走一步"); 28 } 29 } 30 }
测试:
1 public class ChessTest { 2 3 public static void main(String[] args){ 4 Chess chess = new Chess();//实例化象棋 5 chess.setStrategy(new GunStrategy());//接入炮的实现策略 6 chess.straight(5,8);//炮平走 7 8 chess.setStrategy(new SoldierStrategy());//接入兵的实现策略 9 chess.straight(5,8);//兵平走 10 11 chess.setStrategy(new SoldierStrategy());//接入兵的实现策略 12 chess.straight(5,6);//兵平走 13 } 14 }
结果:
1 炮5平8 2 我是兵,我只能平走一步 3 兵5平6