設計模式之美—策略模式

  • 2019 年 10 月 16 日
  • 筆記

策略模式

什麼是策略模式

  策略模式的用意是針對一組演算法,將每一個演算法封裝到具有共同介面的獨立類中,從而使得它們可以相互替換。策略模式使得演算法可以在不影響到客戶端的情況下發生變化

策略模式是對演算法的包裝,是把使用演算法的責任和演算法本身分開。策略模式通常是把一系列的演算法包裝到一系列的策略類裡面,作為一個抽象策略類的子類。

例如下象棋時,炮的前進策略和馬、兵的策略是不一樣的,演算法是有區別的。

我們開始實戰,為了說明問題,我們以上圖為例做一個超級簡單的象棋(簡單到沒法玩象棋,嘿嘿),假設現在象棋只有炮、兵、將,程式碼如下。

 

 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