您好,登錄后才能下訂單哦!
閱讀本文大概需要 1.7 分鐘。
本篇是設計模式系列的第三篇,雖然之前也寫過相應的文章,但是因為種種原因后來斷掉了,而且發現之前寫的內容也很渣,不夠系統。所以現在打算重寫,加上距離現在也有一段時間了,也算是自己的一個回顧吧!
學而時習之,不亦說乎。
推薦閱讀:
從零開始單排學設計模式「UML類圖」定級賽
從零開始單排學設計模式「簡單工廠設計模式」黑鐵III
目前段位: 黑鐵 II
cdn.xitu.io/2019/2/14/168eb35943726dd3?w=568&h=291&f=jpeg&s=7582">
Let's Go!
前言
設計模式不是語法,是一種巧妙的寫法,能把程序變的更加靈活。架構模式比設計模式大,架構模式是戰略,而設計模式是戰術。
設計模式分為3大類型:創建型,行為型,結構型,總共有23種。
策略模式
策略模式是對算法的包裝,是把使用算法的責任和算法本身分割開來,委派給不同的對象管理。策略模式通常把一個系列的算法包裝到一系列的策略類里面,作為一個抽象策略類的子類。
用一句話來說,就是:“準備一組算法,并將每一個算法封裝起來,使得它們可以互換”。
在策略模式(Strategy Pattern)中,一個類的行為或其算法可以在運行時更改。這種類型的設計模式屬于行為型模式。
設計原則有很多,這里直說策略模式中使用到的,參看實例思考哪些地方有用到下面的設計模式:
1. 封裝變化(找出應用中可能需要變化之處,把它們獨立出來,不要和哪些不需要變化的代碼混在一起。)
2. 針對接口,超類編程,而不是針對實現編程。
3. 多用組合,少用繼承。
業務需求
如果讓你設計一個商場收銀軟件,營業員根據客戶所購買商品的單價和數量,向客戶收費。
代碼實現
看到需求的你,對它進行了一個分析,只需要把數量乘以單價就可以得出總費用了,這可難不倒我,然后寫出了最初版本。
很簡單,直接聲明方法然后就計算出結算的總價了。
當你準備提交代碼的時候,萬惡的產品找到你,給出了一個新版的需求。(暗地里畫個圈圈咒詛產品...)
新的業務需求
如果讓你設計一個商場收銀軟件,營業員根據客戶所購買商品的單價和數量,向客戶收費。就是現在商場需要搞活動,會給顧客購買的商品進行打折,比如七五折,九五折等等。
代碼實現
這不是計算完總價格之后,在后面乘以一下折扣就可以了。
經過改版,新的代碼如下:
還沒有等你進行測試,產品就又找上門來了,我們可能后面會實現滿300送100、滿200送50....等等的很多活動,所以你程序需要設計靈活一點哈,不然到時候我的需求可以還會有變動的。
看到這里,沒辦法,還是得繼續完善程序了,想偷個懶都沒有辦法,思考這種種得可能,你找尋這有沒有能完美貼切這種需求得處理方法。
打一折和打九折只是形式的不同,抽象分析出來,所有的打折算法都是一樣的,所以打折算法應該是一個類。冥思苦想下,你又寫出了第三版程序:
這里抽離出來一個現金收費類,現金收取類的抽象方法,收取現金,參數為原價,返回當前價。
正常收費子類,正常收費,原價返回。
打折收費子類
返利收費子類
CashContext類,通過構造方法,傳入具體的收費策略。
客戶端主要代碼
運行結果
現在就再也不怕了,如果再增加新的功能,只需要創建新的子類即可。
策略模式UML類圖
總結
意圖 :定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。
主要解決 :在有多種算法相似的情況下,使用 if...else 所帶來的復雜和難以維護。
何時使用 :一個系統有許多許多類,而區分它們的只是他們直接的行為。
如何解決 :將這些算法封裝成一個一個的類,任意地替換。
關鍵代碼 :實現同一個接口。
應用實例 :
1、諸葛亮的錦囊妙計,每一個錦囊就是一個策略。
2、旅行的出游方式,選擇騎自行車、坐汽車,每一種旅行方式都是一個策略。
3、JAVA AWT 中的 LayoutManager。
優點 :
1、算法可以自由切換。
2、避免使用多重條件判斷。
3、擴展性良好。
缺點 :
1、策略類會增多。
2、所有策略類都需要對外暴露。
使用場景 :
1、如果在一個系統里面有許多類,它們之間的區別僅在于它們的行為,那么使用策略模式可以動態地讓一個對象在許多行為中選擇一種行為。
2、一個系統需要動態地在幾種算法中選擇一種。
3、如果一個對象有很多的行為,如果不用恰當的模式,這些行為就只好使用多重的條件選擇語句來實現。
注意事項 :如果一個系統的策略多于四個,就需要考慮使用混合模式,解決策略類膨脹的問題。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。