設計模式學習---策略模式
最近在看"Head First 設計模式"這本書,便想將自己所學的記錄下來以加深理解,文中肯定有許多不足之處,請各位前輩們指出.
什麼是設計模式
設計模式並不是某種開發語言中的工具,而是我們處理問題時的一種體現,平時在工作我們也總是會使用設計模式,在工作時我們會碰到各種問題,然後我們通過思考,總結.得到出自己的一套處理問題的經驗,或許我們並不知道什麼是設計模式,但是對於某種問題我們已經有了一套解決方案,然後通過觀看它人的程式碼會發現別人處理這類問題與自己總結的相同,其實設計模式就是如此,它是前輩們通過大量的經驗總結了出了一套程式設計思想,然後通過記錄和分享,於是出現了現在程式設計中的聖經----- 23種設計模式 .也就是說設計模式其實並不神祕,但是它卻如此的重要
注:此處所說的問題是程式碼中設計的問題,並不是功能需求問題,例如程式碼的緊耦合
策略模式介紹
下面來說一下第一個設計模式: 策略模式 ,策略模式是一個極其簡單的模式,但也是一個極其常用的模式,下面以一個極其簡單的例子介紹策略模式
現在要為一家商場設計一個促銷功能,不過現在並不知道具體的促銷需求,我們只需將促銷需求設計出來,然後在後期進行新增具體的促銷策略,於是我們快速的完成了這個類的第一版
// 商品類 class Goods { // 商品名稱 public string GoodsName { get; set; } // 商品價格 public decimal GoodsPrice { get; set; } // 促銷方法 public void Discount() { Console.WriteLine("這是促銷方法,目前無促銷"); } }
注:這是一個簡單例子,只為闡述策略模式.
這一個簡單的型別便是第一版的商品類的促銷功能,但是在這裡有一個巨大的問題,就是促銷策略的改變使得我們就必須更改其程式碼.這並符合我們的設計理念,我們觀察程式碼可以得知在這個功能中促銷是一個可變的部分,而我們可以將可變的部分進行分離,現在我們來更改一下程式碼
// 商品類 class Goods { //促銷類引用 public DiscountStrategyClass DiscountStrategyClass { get; set; } // 商品名稱 public string GoodsName { get; set; } // 商品價格 public decimal GoodsPrice { get; set; } // 促銷方法 public void Discount() { //呼叫促銷類的促銷方法 DiscountStrategyClass.Discount(); //Console.WriteLine("這是促銷方法,目前無促銷"); } } // 促銷類 class DiscountStrategyClass { // 促銷方法 public void Discount() { Console.WriteLine("這是促銷方法,目前無促銷"); } }
上面就是我們將促銷方法分離後的程式碼,我建立了一個促銷類,然後在商品類內部建立一個促銷類的引用並在促銷方法呼叫促銷類的促銷方法,然後我們其實很自然的就能想到下一步了,也就是建立抽象促銷類,然後子類進行實現,並約定好自己的促銷策略,而商品類只需宣告並呼叫抽象促銷類促銷方法就可以,
// 商品類 class Goods { //促銷介面引用 public IDiscountStrategy DiscountStrategy { get; set; } // 商品名稱 public string GoodsName { get; set; } // 商品價格 public decimal GoodsPrice { get; set; } // 促銷方法 public void Discount() { //呼叫促銷類的促銷方法 DiscountStrategy.Discount(); //Console.WriteLine("這是促銷方法,目前無促銷"); } } // 促銷類 interface IDiscountStrategy { // 定義促銷方法 void Discount(); } //八折折扣 class EightyPercentDS : IDiscountStrategy { public void Discount() { Console.WriteLine("這是促銷方法,我打八折"); } } //七折折扣 class SevenPercentDS : IDiscountStrategy { public void Discount() { Console.WriteLine("這是促銷方法,我打八折"); } }
這個小的促銷功能就完成了,並且我們可以感覺到在寫程式碼時總是這樣使用
從這裡可以看到策略模式的兩個好處
- 可以在不改變當前結構下新增新的策略
- 可以在執行時動態的改變策略
策略模式體現了兩個原則:
- 找出程式中可能需要變化的地方,把它獨立出來,好讓其它部分不會受到它的影響
- 多用組合,少用繼承
其中策略模式強調的是組合,也就是有一個(HAS-A),只是這裡並沒有很好的體現,在裝飾者模式更能很好的體現
我們在設計編寫程式碼時也要遵守這樣的規則,讓系統變得更有彈性.
策略模式結構
UML
下面是這個簡單的策略模式的UML圖

但在專案中有時候卻會再抽象一層,將環境角色類(當前Goods)抽象成抽象類也就是這樣的UML圖
這樣的UML可以想象成將Goods類變成抽象類,然後再宣告它的子類,例如ComputerGoods(電視),BookGoods(書籍),然後利用繼承的特性來解放實現,也就是我們常說的 面對介面程式設計
注: 面對介面程式設計並不是面對Interface程式設計,而是面對超類程式設計
策略模式定義
定義一個演算法家族,分別封裝起來,讓它們可以互相替換,此模式讓演算法的變化獨立於使用演算法的客戶