通俗易懂設計模式解析——裝飾模式

前言

  今天介紹的是結構型設計模式中的——裝飾模式(Decorator Pattern),也是裝飾器模式。裝飾也就是裝點修飾。例如咱們對手機進行裝飾,買了一個新的手機,先貼個鋼化膜。在帶一個殼。偶爾還在背面貼點貼紙。裝一些掛件。這些等等行爲也就是裝飾。生活中的裝飾是如此,那麼編程中的裝飾模式又是如何呢?html

裝飾模式介紹

1、來由

  在咱們日常的軟件系統中,常常會面臨着向現有的對象添加一些新的功能或者新的職責,可是呢?又不能修改現有的類。以往經常使用的多是繼承來解決次問題。可是採用繼承來講,隨着擴展功能的增長,子類會變化的很膨脹。那麼裝飾器模式呢就解決這麼一個問題,裝飾器模式容許向一個現有的對象添加新的功能職責,同時又不改變其結構。將其功能職責劃分。編程

2、意圖

  動態地給一個對象添加一些額外的職責。就增長功能來講,裝飾器模式相比生成子類更爲靈活。設計模式

3、案例圖

 

 

 

4、裝飾模式代碼示例

看上述案例圖,裝飾模式包含如下部分組成:ide

抽象構件角色給出一個抽象接口,以規範準備接收新加的責任學習

具體構件角色繼承抽象構件角色,定義一個將要接收新加責任的類this

裝飾角色繼承抽象構件角色,包含一個構件角色對象的實例,而且實現抽象構件角色的接口spa

具體裝飾角色繼承裝飾角色,負責新加責任。設計

 

咱們繼續看手機的案例,今天新買了一個手機,須要新加鋼化膜,手機殼,而後纔是一個我想要的手機。在這兒以後忽然又想加一個掛件增長美感。咱們看下如何使用裝飾模式來實現手機裝飾的問題吧:3d

 

namespace Decorator_Pattern
{
    class DecoratorPattern
    {
    }
    #region 抽象構件角色——抽象手機(抽象一個接口,準備接收新增的責任)=========
    /// <summary>
    /// 手機抽象類
    /// </summary>
    public abstract class Phone 
    {
        public abstract void Write();
    }
    #endregion
    #region 具體抽象構件角色——具體手機(實現抽象接口)===============================
    public class HuaweiV9Phone : Phone
    {
        public override void Write()
        {
            Console.WriteLine("對榮耀V9手機開始裝飾");
        }
    }
    #endregion
    #region 裝飾抽象角色——繼承抽象構件角色,包含一個抽象構件角色對象的實例
   /// <summary>
   /// 裝飾角色
   /// </summary>
    public abstract class Decorator : Phone 
    {
        public Phone _phone;
        protected Decorator(Phone phone)
        {
            this._phone = phone;
        }
        public override void Write()
        {
            if (_phone!=null)
            {
                _phone.Write();
            }
        }
    }
    #endregion
    #region 具體裝飾角色——手機加上鋼化膜
    /// <summary>
    /// 具體裝飾角色
    /// </summary>
    public class Membrane : Decorator
    { 
        public Membrane(Phone phone) : base(phone) { }
        public override void Write()
        {
            base.Write();
            AddMembrane();
        }
        public void AddMembrane() 
        {
            Console.WriteLine("手機加上了鋼化膜!");
        }
    }
    #endregion

    #region 具體裝飾角色——手機加上殼
    /// <summary>
    /// 具體裝飾角色
    /// </summary>
    public class Shell : Decorator
    {
        public Shell(Phone phone) : base(phone) { }
        public override void Write()
        {
            base.Write();
            AddShell();
        }
        public void AddShell()
        {
            Console.WriteLine("手機加上了殼!");
        }
    }
    #endregion

    #region 具體裝飾角色——手機掛件
    /// <summary>
    /// 具體裝飾角色
    /// </summary>
    public class Pendant : Decorator
    {
        public Pendant(Phone phone) : base(phone) { }
        public override void Write()
        {
            base.Write();
            AddPendant();
        }
        public void AddPendant()
        {
            Console.WriteLine("手機加上了掛件!");
        }
    }
    #endregion
}

 

    class Program
    {
        static void Main(string[] args)
        {
            //如今得到了一個手機
            Phone phone = new HuaweiV9Phone();

            //裸機一個,先貼個膜
            Decorator membrane = new Membrane(phone);
            membrane.Write();
            Console.WriteLine();

            //仍是以爲不順眼,再加個外殼看看
            Decorator membraneShell = new Shell(membrane);
            //如今我同時有鋼化膜和外殼了
            membraneShell.Write();
            Console.WriteLine( );

            //這時候我以爲仍是不要外殼了。我須要同時又鋼化膜和手機掛件
            Decorator membranePendant = new Pendant(membrane);
            membranePendant.Write();
            Console.WriteLine();


            Console.ReadLine();
        }
    }

 

使用場景及優缺點

1、使用場景

一、須要擴展類的功能或者爲類增長新增的責任code

二、須要動態增長功能或者撤銷功能

2、優勢

一、裝飾類與被裝飾類能夠獨立發展,不會互相耦合, 極易擴展、符合開閉原則

二、裝飾模式與繼承關係的目的都是要擴展對象的功能,可是裝飾模式能夠提供比繼承更多的靈活性。

3、缺點

一、增長系統複雜度,更加易於出錯,難於排查錯誤。增大了學習與理解的難度。

總結

  裝飾模式到這裏就短暫的介紹完了。在日常中,裝飾模式使用的狀況較多。通常來講,咱們擴展一個類常常選擇繼承的方式,可是因爲繼承是爲類引入靜態的特徵。而且隨着功能增長的愈來愈多,子類會愈來愈膨脹。裝飾模式是能夠替代繼承方式的。前面結構型的設計模式也學習了適配器模式與橋接模式。再加上今天學習的裝飾模式。咱們都須要細細分析其區別及使用場景,以便於後期使用時不至於混淆其用法。要用的恰到好處。

只有經歷過地獄般的折磨,纔有征服天堂的力量。只有流過血的手指才能彈出世間的絕唱。

    C#設計模式系列目錄

歡迎你們掃描下方二維碼,和我一塊兒踏上設計模式的闖關之路吧!

  

相關文章
相關標籤/搜索