8、Android設計模式---(時勢造英雄)策略模式

一、介紹,定義

策略模式定義了一系列的算法,並將每一個封裝起來,而且使它們可以相互替換。策略模式讓算法模式獨立於使用它的客戶而獨立變化。

二、使用場景

針對同一類型的問題的多種處理方式,僅僅是具體行爲有差別時。
需要安全地的封裝多種同一類型的操作時。
出現同一抽象類有多個子類,而又需要if-else或者switch-case來選擇具體子類時。

三、UML類圖

Context :用來操作策略的上下文環境;
Stragety:策略的抽象;
StagetyA、StagetyB:具體的策略的實現

四、簡單實現

根據公里數,計算公交車和地鐵的票價
最初版本:

public class PriceCalculator{
    //公交車
     private static final int BUS = 1;
    //地鐵
    private static final int SUBWAY = 2;
    public static void main(String [] args){
        PriceCalculator ca = new PriceCalcluator();
        System.out.println("16公里公交票價:"+ca.calculatePrice(16,SUBWAY ));
        System.out.println("16公里地鐵票價:"+ca.calculatePrice(16,BUS));
    }
    //十公里內1元,超過十公里後,每加一元可乘5公里
    private int busPrice(int km){
        int extraTotal = km-10;
        int extraFactor = extraTotal/5;
        int fraction = extraTotal %5'
        int price = 1+extraFactor*1;
        return fraction >0?++price:price; 
    }
    //6公里內3元,6-12公里4元,12-22公里5元,22-32公里6元
    private int subwayPrice(int km){
        if(km<6){
            return 3;
        }else if(km>6&&km<12){
            return 4;
        }else if(km>12&&km<22){
            return 5;
        }else if(km>22&&km<32){
            return 6;
        }
         return 7;//其他簡化爲7
    }

    int calculatePrice(int km,int type){
        if(type == BUS){
            return busPrice(km);
        }else if(type == SUBWAY){
            return subwayPrice(km);
        }
         return 0;
    }
}

每增加一種出行方式,就要在PriceCalculator中添加一個方法計算出租車出行的價格,並在calculatePrice中添加一個判斷,各種if-else纏繞其中。下面用策略模式重構:
定義一個抽象的價格計算接口:

public interface CalculatorStrategy{
    int calculatePrice(int km);
}

每種方式都實現了此接口:

public class BusStrategy implements CalculatorStrategy{
    @Override
    public int calculatePrice(int km){
        int extraTotal = km-10;
        int extraFactor = extraTotal/5;
        int fraction = extraTotal %5'
        int price = 1+extraFactor*1;
        return fraction >0?++price:price; 
    }
}
public class SubwayStrategy implements CalculatorStrategy{
    @Override
    public int calculatePrice(int km){
        if(km<6){
            return 3;
        }else if(km>6&&km<12){
            return 4;
        }else if(km>12&&km<22){
            return 5;
        }else if(km>22&&km<32){
            return 6;
        }
         return 7;//其他簡化爲7
    }
}

再創建一個扮演Context角色的類

public class TranficCalculator{
    public static void main(String[]args){
        TranficCalculator ca = new TranficCalculator();
        //設置計算策略
        ca.setStrategy(new BusStrategy);
        //計算價格
        System.out.println("16公里公交票價:"+ca.calculatePrice(16));
    }
    CalculatorStrategy mStrategy;
    public void setStrategy(CalculatorStrategy mStrategy){
        this.mStrategy = mStrategy;
    }
    public int calculatePrice(int km){
      return mStrategy.calculatePrice(km);
    }
}

這樣當我們有新的方式時,只要添加一個計算類後設置給TranficCalculator 即可。

五、模式的優缺點:

策略模式主要用來分離算法,根據相同的行爲抽象來做不同的具體策略實現。很好的實現了開閉原則,也就是定義抽象,注入具體實現,從而達到很好的可擴展性。

優點
使用了組合,使架構更加靈活
富有彈性,可以較好的應對變化(開閉原則)
更好的代碼複用性(相對於繼承)
消除大量的條件語句

缺點
隨着策略的增加,子類也會變得繁多。
選擇何種算法需要客戶端來創建對象,增加了耦合,這裏可以通過與工廠模式結合解決該問題

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