設計思想學習—策略模式

策略模式

首先來看一下定義

策略模式(Strategy):定義一組算法,將每個算法都封裝起來,並且使他們之間可以互換

策略模式主要有三點組成

  • 抽象策略角色: 策略類,通常由一個接口或者抽象類實現。
  • 具體策略角色:包裝了相關的算法和行爲。
  • 環境角色:持有一個策略類的引用,最終給客戶端調用。

舉個栗子:
我中午想吃好吃的,但可以吃的東西有很多種:烤鴨、龍蝦、帝王蟹,但是不管吃啥,都是吃,所有就有了抽象策略角色

interface Dine{
    void eat();
}
//下面這些是具體吃啥,也就是具體策略角色
class RoastDuck implements Dine{
    public void eat(){System.out.println("烤鴨真好吃");}
}
class Lobster implements Dine{
    public void eat(){System.out.println("龍蝦真好吃");}
}
class KingCrab implements Dine{
    public void eat(){System.out.println("螃蟹真好吃");}
}
//最後是環境角色
class EatContext{
    Dine dine=null;
    //通過構造方法傳入具體的策略類
    public EatContext(Dine  dine){
        this.dine=dine;
    }
    //實現吃飯
    public void start(){
        dine.eat();
    }
}
//客戶端代碼
public class Client{
    public static void main(String[] args){
        //中午吃龍蝦
        EatContext eat=new EatContext (new Lobster());
        eat.start();
    }
}

策略模式的優點還是很明顯的

  • 算法可以自由的切換,通過實現抽象策略,通過封裝角色對其封裝,保證對外提供“可自由切換”的策略。
  • 避免使用多重條件判斷,如果有多重策略,那麼每個策略只需實現自己的方法,至於採用何種策略,可以通過其他模塊決定。
  • 擴展性良好,可以在現有的系統中任意的加入新的策略,只需繼承策略接口

同樣的缺點也有

  • 策略類數量增多,每個策略都是一個類,複用的可能性很小,類數量增多
  • 所有的策略都需要對外暴露,上層模塊必須知道有哪些策略,然後才能知道採用哪種策略,可以通過使用工廠方法模式、代理模式和享元模式修正。

還記得昨天工廠模式的問題嗎?今天剛好結合策略模式互補。
這裏我直接繼續工廠模式博客的代碼(耦合度高了,不過這個正是我想的,因爲我懶啊!嘿嘿!),我把工廠類和產品直接看成了策略就不再進行更改了(網絡上的都是把簡單工廠和策略模式結合,我這裏是借用這個思想弄出來)

//首先增加策略類
class Strategy{
    private  Factory factory=null;
    private  Operation operation=null;
    //直接把客戶端的判斷邏輯拿過來
    public Strategy(String symbol){
        switch (symbol) {
                case "+":
                    factory=new AddFactory();
                    break;
                case "-":
                    factory=new SubFactory();
                    break;
                case "*":
                    factory=new MulFactory();
                    break;
                case "/":
                    factory=new DivFactory();
                    break;
        }
        operation=factory.creatOperation();
    }
    public double sendResult(double numA,double numB){
        return operation.getResult(numA,numB);
    }
}
//客戶端
public class Calc{
    public static void main(String[] args){
        Scanner sca=new Scanner(System.in);
        System.out.println("請輸入第一個數字");
        String numA=sca.nextLine();
        System.out.println("請輸入算數符號");
        String symbol=sca.nextLine();
        System.out.println("請輸入第二個數字");
        String numB=sca.nextLine();
        double amount=0.0;
        double first=Double.valueOf(numA);
        double second=Double.valueOf(numB);
        Strategy strategy=new Strategy(symbol);
        amount=strategy.sendResult(first,second);
        System.out.println(amount);
    }
}

好了目前的就先寫到這裏了,套用大話設計思想中的一句原話

任何的需求變更都是需要成本的,但成本高低還是有差異的
高手和菜鳥的區別就是,高手可以花同樣的代價獲得更高的收益或者做同樣的事花最小的代價
努力向高手看齊。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章