1. 程式人生 > >設計模式學習---策略模式

設計模式學習---策略模式

很好 方法調用 規則 理念 利用 sco 影響 dsn 讓其

最近在看"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("這是促銷方法,我打八折");
        }
    }

這個小的促銷功能就完成了,並且我們可以感覺到在寫代碼時總是這樣使用
從這裏可以看到策略模式的兩個好處

  1. 可以在不改變當前結構下添加新的策略
  2. 可以在運行時動態的改變策略

策略模式體現了兩個原則:

  1. 找出程序中可能需要變化的地方,把它獨立出來,好讓其它部分不會受到它的影響
  2. 多用組合,少用繼承

其中策略模式強調的是組合,也就是有一個(HAS-A),只是這裏並沒有很好的體現,在裝飾者模式更能很好的體現
我們在設計編寫代碼時也要遵守這樣的規則,讓系統變得更有彈性.

策略模式結構

UML

下面是這個簡單的策略模式的UML圖
技術分享圖片
但在項目中有時候卻會再抽象一層,將環境角色類(當前Goods)抽象成抽象類也就是這樣的UML圖

技術分享圖片

這樣的UML可以想象成將Goods類變成抽象類,然後再聲明它的子類,例如ComputerGoods(電視),BookGoods(書籍),然後利用繼承的特性來解放實現,也就是我們常說的面對接口編程

註: 面對接口編程並不是面對Interface編程,而是面對超類編程

策略模式定義

定義一個算法家族,分別封裝起來,讓它們可以互相替換,此模式讓算法的變化獨立於使用算法的客戶

設計模式學習---策略模式