思考一下:實現某一功能可以有多種算法或策略,我需要根據條件選擇相應的算法或策略來完成該功能。如:排序算法,可以使用冒泡排序、歸併排序、快速排序等。要怎麼實現呢?
很多同學想,寫個類,每個方法是一種排序算法,然後再封裝一個方法寫 if...else... 來判斷要用哪個算法,從而調用對應的方法。顯然這樣寫會使這個類很臃腫,而且如果我要增加一個算法比如堆排序,就必須往裡面加一個方法,然後在 if...else... 後面再加一個 else if. 這就明顯違反了開閉原則和單一職責原則。
今天我們介紹的策略模式,就能優雅的實現這一需求。
定義策略模式定義了一系列的算法,並將每一個算法封裝起來,使他們可以相互替換。策略模式讓算法獨立於使用它的客戶而獨立變化。
使用場景針對同一類型問題的多種處理方式,僅僅是具體行為有差異出現同一抽象類有多個子類(或接口的實現有多個),而又需要用 if-else 或 switch-case 來選擇具體的實現時UMLConcreteStragetyA、ConcreteStragetyB 具體策略的實現實現把需要用到的算法實現通過 setter 注入到原類中,這樣運行時會使用該方法話說東漢末年分三國,烽火連天不休
周瑜想用美人釣來劉備,押住好換荊州
諸葛亮讓趙雲護送,並帶著三個錦囊應對
顯然這三個錦囊就是用來應對的策略,而為什麼要用錦囊裝著不告訴趙雲(策略執行者),那是因為諸葛亮作為一個資深程式設計師,深知「迪米特法則」(aka 最少知識法則)。趙雲只要在合適的時機打開錦囊並執行就可以了。
Shut up and show me the code錦囊接口 - 策略抽象
interface Strategy {
fun name(): String
// 算法策略方法
fun algorithm()
}三個錦囊 - 具體策略
class StrategyFirst : Strategy {
override fun name(): String {
return "第一個錦囊"
}
override fun algorithm() {
println("拜見喬國老,並把劉備娶親的事情搞得東吳人盡皆知")
}
}
class StrategySecond : Strategy {
override fun name(): String {
return "第二個錦囊"
}
override fun algorithm() {
println("用謊言(曹操打荊州)騙泡在溫柔鄉裡的劉備回去荊州")
}
}
class StrategyThird : Strategy {
override fun name(): String {
return "第三個錦囊"
}
override fun algorithm() {
println("讓孫尚香擺平東吳的追兵,她是孫權妹妹,東吳將領懼她三分")
}
}長山趙子龍 - 策略執行者
class Context(val name: String) {
var strategy: Strategy? = null
fun doStrategy() {
println("$name 打開了 ${strategy?.name()}:")
strategy?.algorithm()
}
}Action ! 導演開拍,諸葛亮是編劇
fun main() {
val childDragon = Context("趙雲")
// 到東吳打開第一個錦囊
println("趙雲領命,帶了500 士兵護送劉備前去東吳。到了南徐")
childDragon.strategy = StrategyFirst()
childDragon.doStrategy()
println("吳國太見劉備,同意婚事,假戲真做\n")
// 到年底打開第二個錦囊
println("劉備被新婚度蜜月,忘回荊州,趙雲幾次勸告也無用,到年底")
childDragon.strategy = StrategySecond()
childDragon.doStrategy()
println("次日江邊祭祖,孫尚香一起逃往荊州\n")
// 有追兵無路可走時打開第三個錦囊
println("周瑜派兵追趕,攔住去路")
childDragon.strategy = StrategyThird()
childDragon.doStrategy()
println("孫尚香怒斥追兵,追兵讓路,周瑜後趕上時,關二爺帶著援兵趕到\n")
}最後我們來看戲
在安卓源碼中應用時間插值器 TimeInterpolator ,根據時間流逝的百分比來計算當前屬性值的百分比。系統提供:
加速減速插值器 AccelerateDecelerateInterpolator減速插值器 DecelerateInterpolator 。可以將不同的插值策略運行到屬性動畫中
最後用好策略模式,你就是程式設計師中的「再世諸葛」。