精讀《設計模式 - Strategy 策略模式》
Strategy(策略模式)屬於行爲型模式。
意圖:定義一系列的算法,把它們一個個封裝起來,並且使它們可以相互替換。本模式使得算法可以獨立於使用它的客戶而變化。
策略是個形象的表述,所謂策略就是方案,我們都知道任何事情都有多種方案,而且不同方案都能解決問題,所以這些方案可以相互替換。我們將方案從問題中抽象出來,這樣就可以拋開問題,單獨優化方案了,這就是策略模式的核心思想。
舉例子
如果看不懂上面的意圖介紹,沒有關係,設計模式需要在日常工作裏用起來,結合例子可以加深你的理解,下面我準備了三個例子,讓你體會什麼場景下會用到這種設計模式。
地圖導航
我們去任何地方都可以選擇步行、騎車、開車、公交,不同的方案都可以幫助我們到達目的地,那麼很明顯應該將這些方案變成策略封裝起來,接收的都是出發點和目的地,輸出的都是路線。
佈局方式
比如我們做一個報表系統,在 PC 使用珊格佈局,在移動端使用流式佈局,其實內容還是那些,只是佈局方式會隨着不同終端大小做不同的適配,那麼佈局的適配就是一種策略,它可以與報表內容無關。
我們可以將佈局策略單獨抽取出來,以後甚至可以適配電視機、投影儀等等不同尺寸的場景,而不需要對其他代碼做任何改動,這就是將佈局策略從代碼中解耦出來的好處。
排序算法
當我們調用 .sort
時,使用的是什麼排序算法?可能是冒泡、快速、插入排序?其實無論何種排序算法,本質上做的事情都是一樣的,我們可以事先將排序算法封裝起來,針對不同特性的數組調用不同的排序算法。
意圖解釋
意圖:定義一系列的算法,把它們一個個封裝起來,並且使它們可以相互替換。本模式使得算法可以獨立於使用它的客戶而變化。
算法可以理解爲策略,我們制定許多解決某個場景的策略,這些策略都可以獨立的解決這個場景的問題,這樣下次遇到這個場景時,我們就可以選擇任何策略來解決,而且我們還可以脫離場景,單獨優化策略,只要接口不變即可。
這個意圖本質上就是解耦,解耦之後纔可以分工。想想一個複雜的系統,如果所有策略都耦合在業務邏輯裏,那麼只有懂業務的人才能小心翼翼的維護,但如果將策略與業務解耦,我們就可以獨立維護這些策略,爲業務帶來更靈活的變化。
結構圖
- Strategy: 策略公共接口。
- ConcreteStrategy: 具體策略,實現了上面這個接口。
只要你的策略符合接口,就滿足策略模式的條件。
代碼例子
下面例子使用 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