策略模式

2021-03-06 Android 面試官

思考一下:實現某一功能可以有多種算法或策略,我需要根據條件選擇相應的算法或策略來完成該功能。如:排序算法,可以使用冒泡排序、歸併排序、快速排序等。要怎麼實現呢?

很多同學想,寫個類,每個方法是一種排序算法,然後再封裝一個方法寫 if...else... 來判斷要用哪個算法,從而調用對應的方法。顯然這樣寫會使這個類很臃腫,而且如果我要增加一個算法比如堆排序,就必須往裡面加一個方法,然後在 if...else... 後面再加一個 else if. 這就明顯違反了開閉原則和單一職責原則。

今天我們介紹的策略模式,就能優雅的實現這一需求。

定義

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

使用場景針對同一類型問題的多種處理方式,僅僅是具體行為有差異出現同一抽象類有多個子類(或接口的實現有多個),而又需要用 if-else 或 switch-case 來選擇具體的實現時UML

ConcreteStragetyA、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 。

可以將不同的插值策略運行到屬性動畫中

最後

用好策略模式,你就是程式設計師中的「再世諸葛」。

相關焦點

  • 設計模式——策略模式
    策略模式策略這個詞應該怎麼理解,打個比方說,我們出門的時候會選擇不同的出行方式,比如騎自行車、坐公交、坐火車、坐飛機、坐火箭等等,這些出行方式,每一種都是一個策略。策略模式(Strategy):它定義了算法家族,分別封裝起來,讓它們之間可以互相替換,此模式讓算法的變化,不會影響到使用算法的客戶。
  • 策略模式(上)
    今年開始深入學習設計模式,並把所思所想記錄下來,以備查閱。因為我以《Head First 設計模式》一書為導向,所以第一個學習的模式是策略模式。本篇為策略模式的上篇,我以傳統的嚴格意義上的面向對象語言 Java為例來說明此模式;我會在下一篇用非嚴格意義上的OO語言 Go基於同樣的例子進行說明。
  • Java策略模式
    在策略模式中,可以在運行時更改類行為或其算法。 這種類型的設計模式屬於行為模式。在策略模式中,創建表示各種策略對象和其行為根據其策略對象而變化的上下文對象。 策略對象更改上下文對象的執行算法。實現實例在這個示例中,將創建一個 Strategy 接口,定義實現策略接口的操作和具體策略類。 上下文類- Context 是使用策略的類。StrategyPatternDemo是一個演示類,將使用上下文- Context 和策略對象來演示上下文行為基於其部署或使用的策略的變化。
  • 設計模式之策略模式
    行為型設計模式策略模式一簡介當一個對象有多種行為要執行時,我們可以使用策略模式,讓對象自由選擇執行的行為種類,避免使用if…else if….else if…這種嵌套代碼如果我們使用策略模式,某個行為要修改代碼,我們只要修改對應行為的類,都不用動到舊代碼。後期如果要撤掉某種行為或增加某種行為,都比較方便。二例子假設系統維護裡,會發送命令:分析系統cpu使用情況,分析系統memory使用情況,分析系統io情況。後端系統執行命令後,將結果傳回前端,供界面展示結果,畫趨勢圖。
  • Java設計模式之策略模式詳解
    前言在軟體領域中,設計模式作為一種經典的開發實踐常常需要我們去深入的理解,而策略模式作為設計模式的一種,使用頻率也是相對來說比較高的,在Java中,當我們學習TreeSet集合的時候,就採用了經典的策略模式的思想,本文主要講解策略模式。
  • 掃盲:策略模式,成事兒還需要策略
    掃盲系列只會講重點的設計模式,對於部分簡單的設計模式,不會花太多篇幅。此外,對於設計模式,本身都很相似,很難界定,如果你有自己的想法,一定要勇敢站出來和大家 argue。好的,就這樣,今天就帶來第一篇設計模式:策略模式。什麼是策略模式?生活中的策略策略模式在生活中體現很多。
  • 閱讀策略的教學模式解讀
    大量的閱讀策略教學研究均基於後兩種研究取向。下文介紹四種經研究發現對學生閱讀理解能力提升幫助較大的、著名的閱讀策略教學模式。互惠教學模式是帕林薩和布朗根據維果茨基的最近發展區理論發展起來的一種閱讀教學模式。
  • 設計模式之策略模式(Java實現例子說明)
    設計模式之策略模式小王在和同事正在吹牛時,領導過來了,小王啊,你又在吹牛了?別吹了,幹點正活,下周要去春遊,你給出幾種方案。小王一聽去旅遊,屁顛屁顛地去幹活了。這個其實就是一個設計模式,叫做策略模式。策略模式(Strategy Pattern):定義一組算法,將每個算法封裝起來,並且使他們之間可以互換。策略模式是一個簡單的模式也叫做政策模式。
  • 乾貨,策略模式你不知道的
    百度一搜,策略模式想必各類文章都有,今天講一講你在其他地方看不到的策略模式的思想。代碼誰都會寫,思想不是誰都有的。策略模式上節我們稍微的探討了下SpringSession中包含的設計模式。SpringSession 設計模式分析這節我們應用下SpringSession 所涉及的策略模式。
  • 策略模式,看這一篇就夠了
    策略模式官方定義為,一個類的行為或其算法可以在運行時更改,讀起來意思很模糊,也很難理解。下面我們就一步一步寫代碼來實現策略模式。當然上面的這些並不是策略模式,這只是順帶講一下comparable,哈哈,下面的comparator的實現才是策略模式。接著上面的來講,如果我想貓的比較大小的策略可以靈活的指定,就是說我想通過身高來比較貓的大小,不通過體重了。有人會說重新寫一遍compareTo裡面的判斷,這肯定不符合我們的風格,開閉原則大家都還記得吧,對修改關閉,對拓展開放。
  • C語言,去你的策略模式!
    因此對於文章的內容,請大家主要關注、體會設計模式本身,更多地去考慮程序的可擴展性和可維護性。文章本身是希望向C語言愛好者普及設計模式的知識,在所有的程序設計中,本意都是儘可能地簡單易懂。因此拋開設計模式的本意去討論程序的代碼實現優劣,是沒有任何意義的。
  • 用戶決策的不同模式及營銷策略
    編輯導語:影響用戶決策的因素有很多,在面對不同價值、不同用途的商品時,用戶會有不同的決策模式;比如你買一樣很貴的商品時,你會經過多種對比,思前想後,最後決定下單;本文作者分享了關於用戶決策的不同模式以及營銷策略,我們一起來看一下。
  • 教學設計的模式和教學策略的分類
    教學設計過程的模式則是在教學設計的實踐當中逐漸形成的,運用系統方法進行教學開發、設計的理論的簡化形式。教學設計的一般模式是適合於多種設計類型的教學模式,需要找到教學設計的基本組成部分。教學設計者在教學設計實踐的基礎上總結出教學設計過程的基本要素,如圖1-1所示。通過對教學設計模式的基本構成要素的分析,以及教學設計的實踐,我們得出教學設計的一般模式,如圖1-2所示。
  • 【教】教學設計的模式和教學策略的分類
    模式是再現現實的一種理論性的簡化形式。教學設計過程的模式則是在教學設計的實踐當中逐漸形成的,運用系統方法進行教學開發、設計的理論的簡化形式。教學設計的一般模式教學設計的一般模式是適合於多種設計類型的教學模式,需要找到教學設計的基本組成部分。教學設計者在教學設計實踐的基礎上總結出教學設計過程的基本要素,如圖1-1所示。
  • Vue 騷技巧,策略模式實現動態表單驗證
    封裝的策略算法一般是獨立的,策略模式根據輸入來調整採用哪個算法。關鍵是策略的實現和使用分離。3. 策略模式的通用實現根據上面的例子提煉一下策略模式,折扣計算方式可以被認為是策略(Strategy),這些策略之間可以相互替代,而具體折扣的計算過程可以被認為是封裝上下文(Context),封裝上下文可以根據需要選擇不同的策略。
  • 教學方法、教學策略、教學模式三者的區別與聯繫
    一、聯繫從理論向實踐轉化的階段或順序看,是從教學理論到教學模式,再到教學策略,再到教學方法,再到教學實踐,教學策略是對教學模式的進一步具體化,教學模式包含教學策略。教學模式規定教學策略、教學方法,屬於較高層次。教學策略比教學模式更詳細、更具體,受教學模式的制約。
  • ...設計模式:實戰策略模式「模擬多種營銷類型優惠券,折扣金額計算...
    策略模式是一種行為模式,也是替代大量ifelse的利器。六、策略模式重構代碼。接下來使用策略模式來進行代碼優化,也算是一次很小的重構。與上面面向流程式的開發這裡會使用設計模式,優惠代碼結構,增強整體的擴展性。1.
  • 通俗易懂的告訴你「策略模式」在java多線程中的應用
    下面我們就一起來看看「策略模式」是如何運用在javaduo線程中的。01什麼是「策略模式」廢話少說,先看定義!根據不同的情況選擇不同的付款方式,這其實就有些類似我們的策略模式。再結合「策略模式」的定義大致就能明白什麼是「策略模式」03「策略模式」在多線程的應用了解完什麼是「策略模式」之後,我們再來看一看在java
  • 你有張良計,我有過牆梯之策略模式
    0x01:策略模式簡介 策略模式指對象有某個行為,但是在不同的場景中,該行為有不同的實現算法。比如每個人都要交個人所得稅,但是根據個人的收入情況,個人所得稅的計算算法是有不同的策略的。
  • 程式設計師必學設計模式,策略模式,讓你少改代碼提升效率
    經常有人會說,程式設計師寫代碼要什麼設計模式,隨便寫就行,這其實是一種很不好的習慣,就好比蓋房子,不需要設計圖隨便蓋就可以,但是想要蓋成高樓大廈,一定要經過嚴謹的設計,不然就容易崩塌。我們採用設計模式來寫代碼,更多的,是為了不坑自己。