天天看點

設計模式系列-裝飾模式

一、上篇回顧

      通過上篇的簡單描述,我們知道了橋接模式主要是為了解決,一個對象的多個次元的變化因素的變化太快,難以控制的問題,我們通過将每個次元

的變化因素進行抽象, 然後我們的對象隻要依賴于抽象即可,具體的實作調用我們不關心,通過對象組合的方式,我們就能組合出我們想要的對象。無

疑這是一種非常靈活的也是滿足設計模式的原則的,抽象和實作分離,使他們各自發生變化都不受對方的影響。而且我們也講述了,使用橋接模式的幾

個典型的場景,現在我們的實際項目中就有這樣的問題,我也是在項目的使用過程中加深對橋接模式的了解的,橋接模式為系統在多個次元的變化的适

應性方面提供了很好的參考,特别适合底層架構的開發過程中使用,可以适應不同變化因素的改變。上篇橋接模式放出後,我也得到了不少朋友的反

饋,很感謝大家,這裡特别的感謝一個名叫“蕭蕭”的朋友,他指出了我在文章中給出的例子有些不妥之處,我本篇将會對上篇中給出的例子,從給出

符合橋接模式的實作,這裡對大家say sorry !

      上篇中的實作:

   public interface IORM

   {

       ISave Save

       {

           get;

           set;

       }

       IDelete Delete

       ICreate Create

       ICache Cache

       IQuery Query

       void Test();

   }

   我們在這個接口的定義中并沒有展現橋接模式中的變化因素的抽象的概念,我們修改為如下形式:

public interface IORM

       }

       void Test();

public interface ICache

{

    object Cache(object o);

}

public interface IQuery

    object Query(string condition);

具體的緩存服務與查詢服務的實作:

public class Cache : ICache

        { 

           public  object Cache(object o){

                 return o;

                }

        }

public class Query: IQuery

           public  object Query(string condition){

                 return GetList(condition);

具體的ORM實作代碼如下:

public class ORM : IORM

    {

        private IQuery query=new Query();

        private ICache cache=new Cache();

        public ORM(IQuery query,ICache cache)

        {

          this.query=query;

          this.cache=cache;

        public ISave Save

        {

            get

            {

                throw new NotImplementedException();

            }

            set

        }

        public IDelete Delete

        public ICreate Create

        public void Test()

            ///測試緩存對象!

            this.cache.Cache(new object());

    }

      對于之前按照我給的思路的方式,請大家糾正下思路,我這裡對大家造成的誤解,表示抱歉,因為我舉例子的時候,表述的和我們本文的初衷有些

偏差,希望大家見諒,請大家繼續提出寶貴意見和建議。

二、摘要

        本篇将會開始講述結構型模式中的很有技巧性的模式之一-裝飾模式,我們了解的裝飾就是給類穿個衣服,或者裝扮一下,讓某個類具有一個新的特性或者新的

職責。我們在應對對于通過類的繼承來實作類擴充功能時候的膨脹的速度過快的問題,我想這個也是我們上一篇講述的橋接模式中提到的一些問題,不過裝飾模式和

橋接模式的側重點稍微不同。裝飾模式更側重的是某個類型的功能經常的動态的增加的情況。那麼如果我們通過繼承的方式來實作,那麼将會是噩夢。繼承複繼承,

繼承何其多,然而通過裝飾模式,我們就能很優雅的為某個類型添加新的職責。我們也知道,由于C#不支援多繼承,我們隻能為某個類型添加新增功能的時候,我們

隻能單繼承+多實作接口的形式來為類型添加新的功能。而裝飾模式可以很優雅的解決這樣的問題。

         裝飾模式的主要目的就是:動态的為某個類型添加新的職責。

          我們來看看裝飾模式的過程吧:

設計模式系列-裝飾模式

           我們将自己開發一個簡單的播放器,我們通過第一次裝飾可以為播放器增加播放音樂的功能,具體包括播放所有的音頻格式檔案,通過第二次裝飾,我們可

以為這個播放器添加播放視訊格式檔案的功能,這時候,如果我們想要一個萬能的播放器,那麼我們将通過2次裝飾來完成這個播放器的類型職責的添加。

三、本文大綱

       a、上篇回顧。

       b、摘要。

       c、本文大綱。

       d、裝飾模式的特點及使用場景。

       e、裝飾模式的經典實作。

       f、裝飾模式的其他方案。

       g、裝飾模式使用總結。

       h、系列進度。

       i、下篇預告。

四、裝飾模式的特點及使用場景

      4.1、裝飾模式的特點

        裝飾模式:裝飾模式主要是解決了,我們以動态的,透明的形式為某個類型添加一個新的職責,客戶程式可以不知道我們具體添加的功能職責,

而客戶程式隻是根據對象提供的方法進行調用即可。而具體職責操作留給裝飾對象去完成。

        我們這裡給出裝飾模式的經典模式的類圖:

        我們這裡對這個經典結構進行稍微的說明:我們這裡結合我們上面的播放器來說

        1、對于Compnent,我們定義一個IPlayer這樣的接口,我們接口中定義方法,Play()方法。

        2、然後我們把要裝飾這個播放器的裝飾類型進行抽象,抽象出接口IDecorator接口。這個即可繼承自IPlayer接口。

        3、接着,我們定義一個簡單的播放器對象,實作這個IPlayer接口。

        4、我們實作播放音樂和視訊檔案的裝飾類型的實作。

        5、我們将簡單的播放器對象,通過裝飾對象進行裝飾,為這個簡單點傳播放器套上一層一層的外殼,使其具有播放音樂和視訊的功能。

      4.2、裝飾模式的使用場景

         1、當我們需要為某個現有的對象,動态的增加一個新的功能或職責時,可以考慮使用裝飾模式。

         2、适應于某個對象的職責經常發生變化或者經常需要動态的增加職責,避免因為這種為了适應這樣的變化,而增加繼承子類擴充的方式,因為

這種方式為 造成,子類膨脹的速度過快,難以控制。

五、裝飾模式的經典實作

        經過上面的簡單描述,我想大家很想知道裝飾模式的經典實作方案吧!我們來結合播放器的執行個體來分析實作,下面給出核心代碼:

   /// <summary>

   /// 簡單點傳播放器的統一接口

   /// </summary>

   public interface IPlayer

       void Play();

    /// <summary>

    /// 播放器的普通實作類

    /// </summary>

    public class Player : IPlayer

        #region IPlayer 成員

        public void Play()

            throw new NotImplementedException();

        #endregion

   /// 裝飾器接口

    public  interface IDecorator : IPlayer

    /// 裝飾器的抽象基類

    public abstract class DecoratorBase : IDecorator

        protected IPlayer play = null;

        public DecoratorBase(IPlayer player)

            this.play = player;

        public abstract void Play();

    /// 音樂播放器裝飾器

     public class MusicDecorator : DecoratorBase

         public MusicDecorator(IPlayer play)

            : base(play)

        public override void Play()

    /// 視訊播放器裝飾類

    public class VedioDecorator : DecoratorBase

        public VedioDecorator(IPlayer play)

   具體的測試調用代碼如下:

        static void Main(string[] args)

            IPlayer play = new Player();

            play = new MusicDecorator(play);

            play = new VedioDecorator(play);

經過了2次的裝飾後,該播放器對象,可以播放任何格式的檔案。通過上面的過程,我們發現了我們在使用裝飾模式的時候,有如下幾點我們需要把我好:

1、我們在開發的過程中,如果需要為某個類型添加多個職責的時候,我們需要多個裝飾實作類,這樣類太多的時候,我們需要将這個對象裝飾多次。

2、我們對我們的裝飾過的對象,如何指定的撤銷某個裝飾過程的狀态呢?類似我們使用某些應用程式中的undo操作。

3、對于動态裝飾的對象,我們debug的時候,我們很難跟蹤和調試。

六、裝飾模式的其他方案

             裝飾模式的具體過程如下:

設計模式系列-裝飾模式
       一、通過配置檔案來完成裝飾操作

       具體的操作過程如下:配置檔案中配置對象要完成的裝飾步驟,通過公共的配置讀取類,通過字典緩存裝飾的步驟,然後傳入普通的對象,傳回裝

飾後的對象。

設計模式系列-裝飾模式

       我們這裡給出配置檔案的格式:

<?xml version="1.0" encoding="utf-8" ?>

<Decorator>

  <Section>

    <Class  name="" type="">

      <Step name="" type=""/>

    </Class>

  </Section>

</Decorator>

我們來看具體的裝飾器步驟構造器代碼:

    public class DecoratorFactory

        public static T BuilderPlay<T>(T play)

            Dictionary<Type, List<IDecorator>> steps = new Dictionary<Type, List<IDecorator>>();

            List<IDecorator> list = steps[typeof(T)];

            foreach (IDecorator item in list)

                play = (T)Activator.CreateInstance(item.GetType(), play);

            return play;

       二、通過特性+反射的形式來組織裝飾的過程

設計模式系列-裝飾模式
       這裡就不給出具體的實作代碼了,下篇或者後續給出分析幾類基于特性+标記的實作方案。大夥也可以提出其他的不同實作思路。

七、裝飾模式使用總結

        通過上面的講述,我們知道裝飾模式,特别适合對某個類型的對象,動态的增加新的職責,應用程式就像使用原來的對象一樣使用對象新增的裝飾後的功能,裝

飾模式就好像是穿了一層層的外殼,這樣的方式避免了通過繼承來為類型添加新的職責的形式可取,通過繼承的方式容易造成子類的膨脹,但是當裝飾類太多的時

候,也是個難以維護的問題,至少是在裝飾對象的時候,我們可能需要多步操作來完成對象的裝飾,這時候我們可以同上面提出的改進的方案,來完成自動配置裝飾

模式,記錄操作模式的狀态,可以進行有效的復原操作,以完成撤銷操作。

八、系列進度

建立型

        1、

系統架構技能之設計模式-單件模式         2、 系統架構技能之設計模式-工廠模式         3、 系統架構技能之設計模式-抽象工廠模式         4、 系統架構技能之設計模式-建立者模式         5、 系統架構技能之設計模式-原型模式 結構型 系統架構技能之設計模式-組合模式 系統架構技能之設計模式-外觀模式 系統架構技能之設計模式-擴充卡模式 系統架構技能之設計模式-橋模式 系統架構技能之設計模式-裝飾模式

        6、系統架構技能之設計模式-享元模式

        7、系統架構技能之設計模式-代理模式

行為型

        1、系統架構技能之設計模式-指令模式

        2、系統架構技能之設計模式-觀察者模式

        3、系統架構技能之設計模式-政策模式

        4、系統架構技能之設計模式-職責模式

        5、系統架構技能之設計模式-模闆模式

        6、系統架構技能之設計模式-中介者模式

        7、系統架構技能之設計模式-解釋器模式

九、下篇預告

      下篇我們将會講述結構性模式中的-享元模式,該模式主要的用處呢,就是減少我們在程式開發過程中的過多的對象執行個體,有些情況下,其實我們

可以共享這些執行個體,來提高程式的性能,我們下篇将會講述這個模式,請大家繼續支援我!謝謝!您的支援是我前進的動力!。

作者:

IT行者-何戈洲

出處:

http://www.cnblogs.com/hegezhou_hot/

2007年大學畢業後便投入到計算機行業中,先後涉足(電信、電子商務、教育、醫療、工程建築、項目管理、房産)等行業,目前有比較豐富的技術及行業經驗,技術方面涉及(Java、Go、.NET、Python、設計模式、系統架構、PM管理流程、軟體工程、靈活開發、SOA、雲計算、大資料、區塊鍊、WF、SAAS等領域),結合業務可提供(EIP、ERP、HIS、B2B、B2C、B2B2C、CRM、OA、O2O等)業務及技術解決方案,随着時間的推移,目前已逐漸轉向管理方面,歡迎同行一起交流學習,個人平時愛好體育運動、音樂、旅遊等,向往豐富多彩的生活旅程。如有問題或建議,請多多賜教!

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,如有問題,可以通過

[email protected]

 聯系我,非常感謝。

其他聯系方式:

電話:13716055594

聯系人:何戈洲

微信聯系我:

設計模式系列-裝飾模式
回報文章品質,你可以通過快速通道評論:

繼續閱讀