《Android源码设计模式解析与实战》读书笔记(七)——策略模式
第六章抽象工廠模式實在是不好理解,我覺得也不能似懂非懂就算了,畢竟這次決定第一遍通讀起碼要搞懂各種設(shè)計模式的基本思想,在源碼中如何體現(xiàn)都可以等到閱讀代碼的能力上去了慢慢消化,但是概念什么的,還是不能就這么跳過了,既然不太好理解,就先放一放,沒準(zhǔn)什么時候就豁然開朗了,先讀讀后面的模式換換腦子。
第七章 時勢造英雄——策略模式
在開發(fā)過程中經(jīng)常會實現(xiàn)某個功能而需要加入多種算法或策略,然后根據(jù)具體情況來選擇不同的算法來實現(xiàn)該功能。針對這種情況,一般的常規(guī)方法是把多種算法寫在一個類里面,然后根據(jù)if...else...或者switch...case...條件判斷語句來決定具體使用哪種算法。但是這樣做的話,這個類就會顯得太臃腫,維護成本相應(yīng)變高,維護時發(fā)生錯誤的幾率也會相應(yīng)增高,而且如果我們需要增加一種新的算法的時候,就得修改源代碼,還要增加新的if...else...判斷或者新的case...語句。這很明顯違背了開閉原則和單一職責(zé)原則,所以,才產(chǎn)生了策略模式。
策略模式將這些算法或者策略抽象出來,提供一個統(tǒng)一的接口,不同的算法或者策略有不同的實現(xiàn)類,這樣客戶端就可以通過注入不同的實現(xiàn)類來實現(xiàn)算法或者策略的動態(tài)替換了,可擴展性和可維護性也就增強了。
1.定義
策略模式定義了一系列的算法,并將每一個算法封裝起來,它們直接可以相互替換。策略模式讓算法獨立于使用它的客戶,并可以獨立變化。
2.使用場景
1).針對同一類型問題的多種處理方式,僅僅是具體行為有差別時。
2).需要安全的封裝多種同一類型的操作時。
3).出現(xiàn)同一抽象類有多個子類,而又需要使用if...else...或者switch...case...來選擇具體子類時。
3.簡單實現(xiàn)
以乘坐交通工具的費用計算為例,乘坐公交車、地鐵、出租車的費用計算方式肯定是不一樣的,但是它們的功能都是一樣的,都是計算出行成本的。
我們可以先定義一個價格計算接口:
public interface CalculateStrategy {/*** Description:根據(jù)路程來計算價格,* Date:2017/5/11* @param km: 路程* @return :計算出來的價格*/int calculatePrice(int km); }然后是各種交通工具的具體計算策略類: public class BusStrategy implements CalculateStrategy {/*** Description:以北京公交車為例,10公里之內(nèi)1塊錢,超過10公里后每5公里1塊錢* Date:2017/5/11*/@Overridepublic int calculatePrice(int km) {if (km <= 10) {//10公里以內(nèi)return 1;} else {//超過10公里的距離int beyondKm = km - 10;//超過的距離是5公里的幾倍int multiple = beyondKm / 5;//超過的距離對5公里取余int fraction = beyondKm % 5;int price = 1 + multiple * 1;//如果最后取余大于5公里,也按5公里算,如果剛好是5公里的倍數(shù)則不用.return fraction > 0 ? ++price : price;}} }
public class SubwayStrategy implements CalculateStrategy {/*** Description:6公里(含)內(nèi)3塊錢,6-12公里(含)4塊錢,12-22公里(含)5塊錢,22-32公里(含)6塊錢,再增加距離則統(tǒng)一簡化為7塊錢* Date:2017/5/11*/@Overridepublic 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;} else {return 7;}} }
然后增加一個扮演客戶端的類:
public class TrafficCalculator {private static TrafficCalculator sTrafficCalculator = new TrafficCalculator();public static TrafficCalculator getInstance() {return sTrafficCalculator;}private CalculateStrategy mCalculateStrategy;public void setmCalculateStrategy(CalculateStrategy mCalculateStrategy) {this.mCalculateStrategy = mCalculateStrategy;}public int calculatePrice(int km) {return mCalculateStrategy.calculatePrice(km);} }
這樣一來,如果要加入新的策略,不用去修改源代碼了,比如要增加出租車的計價策略,只需要新增一個出租車價格計算策略類:
public class TaxiStrategy implements CalculateStrategy {/*** Description:簡化為價格為路程的2倍,不要在意這些細(xì)節(jié)* Date:2017/5/11*/@Overridepublic int calculatePrice(int km) {return km * 2;} }計算價格時:
TrafficCalculator mTrafficCalculator = TrafficCalculator.getInstance();mTrafficCalculator.setmCalculateStrategy(new BusStrategy());System.out.println("Bus Price:" + mTrafficCalculator.calculatePrice(20));
mTrafficCalculator.setmCalculateStrategy(new SubwayStrategy());System.out.println("Subway Price:" + mTrafficCalculator.calculatePrice(20));mTrafficCalculator.setmCalculateStrategy(new TaxiStrategy());System.out.println("Taxi Price:" + mTrafficCalculator.calculatePrice(20));
通過這個示例可以很明顯的看出來,雖然使用if...else...判斷的話可能只需要一個類甚至一個方法就可以了,看起來比較簡單,但是確實顯得很臃腫,而且邏輯復(fù)雜,難以維護,幾乎沒有什么結(jié)構(gòu)可言。但是使用策略模式的話則是建立抽象,將每種策略變成一個具體的策略實現(xiàn)類,通過不同的算法替換,在簡化邏輯,優(yōu)化結(jié)構(gòu)的同時,增強了代碼的可讀性、可擴展性和可維護性。
4.總結(jié)
策略模式主要是用來分離算法,在相同的策略抽象下有不同的具體實現(xiàn)策略。策略模式很好的詮釋了開閉原則,也就是定義抽象,注入不同的實現(xiàn),以達(dá)到增強可擴展性的目的。
優(yōu)點:
1).結(jié)構(gòu)清晰,使用簡單。
2).耦合度降低,擴展方便。
3).封裝更徹底,數(shù)據(jù)也更安全。
缺點:
1).隨著策略的增加,子類會相應(yīng)增多。
Demo下載
總結(jié)
以上是生活随笔為你收集整理的《Android源码设计模式解析与实战》读书笔记(七)——策略模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: iOS前期OC训练OC_10Block
- 下一篇: android sina oauth2.