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

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

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

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

舉例子

如果看不懂上面的意圖介紹,沒有關係,設計模式需要在日常工作裏用起來,結合例子可以加深你的理解,下面我準備了三個例子,讓你體會什麼場景下會用到這種設計模式。

地圖導航

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

佈局方式

比如我們做一個報表系統,在 PC 使用珊格佈局,在移動端使用流式佈局,其實內容還是那些,只是佈局方式會隨着不同終端大小做不同的適配,那麼佈局的適配就是一種策略,它可以與報表內容無關。

我們可以將佈局策略單獨抽取出來,以後甚至可以適配電視機、投影儀等等不同尺寸的場景,而不需要對其他代碼做任何改動,這就是將佈局策略從代碼中解耦出來的好處。

排序算法

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

意圖解釋

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

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

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

結構圖

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

代碼例子

下面例子使用 typescript 編寫。

 1interface Strategy {
 2  doSomething: () => void
 3}
 4
 5class Strategy1 implements Strategy {
 6  doSomething: () => {
 7    console.log('實現方案1')
 8  }
 9}
10
11class Strategy2 implements Strategy {
12  doSomething: () => {
13    console.log('實現方案2')
14  }
15}
16
17
18new System(new Strategy1()) 
19new System(new Strategy2()) 
20複製代碼
21

弊端

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

總結

策略模式是很重要的抽象思維,我們首先要意識到問題有許多種解法,才能意識到策略模式的存在。當一個問題需要採取不同策略,且策略相對較複雜,且未來可能要拓展新策略時,可以考慮使用策略模式。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://juejin.cn/post/6939707969223262238?utm_source=gold_browser_extension