精讀《設計模式 - Strategy 策略模式》

Strategy(策略模式)

Strategy(策略模式)屬於行爲型模式。前端

意圖:定義一系列的算法,把它們一個個封裝起來,而且使它們能夠相互替換。本模式使得算法能夠獨立於使用它的客戶而變化。git

策略是個形象的表述,所謂策略就是方案,咱們都知道任何事情都有多種方案,並且不一樣方案都能解決問題,因此這些方案能夠相互替換。咱們將方案從問題中抽象出來,這樣就能夠拋開問題,單獨優化方案了,這就是策略模式的核心思想。github

舉例子

若是看不懂上面的意圖介紹,沒有關係,設計模式須要在平常工做裏用起來,結合例子能夠加深你的理解,下面我準備了三個例子,讓你體會什麼場景下會用到這種設計模式。算法

地圖導航

咱們去任何地方均可以選擇步行、騎車、開車、公交,不一樣的方案均可以幫助咱們到達目的地,那麼很明顯應該將這些方案變成策略封裝起來,接收的都是出發點和目的地,輸出的都是路線。typescript

佈局方式

好比咱們作一個報表系統,在 PC 使用珊格佈局,在移動端使用流式佈局,其實內容仍是那些,只是佈局方式會隨着不一樣終端大小作不一樣的適配,那麼佈局的適配就是一種策略,它能夠與報表內容無關。設計模式

咱們能夠將佈局策略單獨抽取出來,之後甚至能夠適配電視機、投影儀等等不一樣尺寸的場景,而不須要對其餘代碼作任何改動,這就是將佈局策略從代碼中解耦出來的好處。數組

排序算法

當咱們調用 .sort 時,使用的是什麼排序算法?多是冒泡、快速、插入排序?其實不管何種排序算法,本質上作的事情都是同樣的,咱們能夠事先將排序算法封裝起來,針對不一樣特性的數組調用不一樣的排序算法。微信

意圖解釋

意圖:定義一系列的算法,把它們一個個封裝起來,而且使它們能夠相互替換。本模式使得算法能夠獨立於使用它的客戶而變化。佈局

算法能夠理解爲策略,咱們制定許多解決某個場景的策略,這些策略均可以獨立的解決這個場景的問題,這樣下次遇到這個場景時,咱們就能夠選擇任何策略來解決,並且咱們還能夠脫離場景,單獨優化策略,只要接口不變便可。優化

這個意圖本質上就是解耦,解耦以後才能夠分工。想一想一個複雜的系統,若是全部策略都耦合在業務邏輯裏,那麼只有懂業務的人才能當心翼翼的維護,但若是將策略與業務解耦,咱們就能夠獨立維護這些策略,爲業務帶來更靈活的變化。

結構圖

  • Strategy: 策略公共接口。
  • ConcreteStrategy: 具體策略,實現了上面這個接口。

只要你的策略符合接口,就知足策略模式的條件。

代碼例子

下面例子使用 typescript 編寫。

interface Strategy {
  doSomething: () => void
}

class Strategy1 implements Strategy {
  doSomething: () => {
    console.log('實現方案1')
  }
}

class Strategy2 implements Strategy {
  doSomething: () => {
    console.log('實現方案2')
  }
}

// 使用
new System(new Strategy1()) // 策略1實現的系統
new System(new Strategy2()) // 策略2實現的系統

弊端

不要走極端,不要每一個分支走一個策略模式,這樣會致使策略類過多。當分支邏輯簡單清晰好維護時,不須要使用策略模式抽象。

總結

策略模式是很重要的抽象思惟,咱們首先要意識到問題有許多種解法,才能意識到策略模式的存在。當一個問題須要採起不一樣策略,且策略相對較複雜,且將來可能要拓展新策略時,能夠考慮使用策略模式。

討論地址是: 精讀《設計模式 - Strategy 策略模式》· Issue #304 · dt-fe/weekly

若是你想參與討論,請 點擊這裏,每週都有新的主題,週末或週一發佈。前端精讀 - 幫你篩選靠譜的內容。

關注 前端精讀微信公衆號

版權聲明:自由轉載-非商用-非衍生-保持署名( 創意共享 3.0 許可證
相關文章
相關標籤/搜索