1. 程式人生 > >C#設計模式——裝飾者模式

C#設計模式——裝飾者模式

方式 實例 oid spa als note 客戶 基本功 pan

一、裝飾者模式介紹:

裝飾者模式——以對客戶透明的方式動態地給一個對象添加額外的職責,采用對象組合而非繼承的方式實現了再運行時動態地擴展對象功能的能力,相比生成子類可以更靈活地增加功能,而且可以根據需要擴展多個功能,避免了單獨使用繼承帶來的靈活性差和多子類衍生問題。同時它很好地符合面向對象設計原則中 ”優先使用對象組合而非繼承“和”開放-封閉“原則。

二、背景:

在軟件開發中,我們經常想要對一類對象添加不同的功能,例如要給筆記本添加貼膜,筆記本外設鍵盤,輔助扇熱風扇等,如果此時利用繼承來實現的話,就需要定義無數的類,如貼膜筆記本類StickerNoteBook、筆記本外設類PeripheralsNoteBook等,這樣就會導致 ”子類爆炸“問題,為了解決這個問題,裝飾者模式出現了。

三、裝飾者模式中的各個角色:

  • 抽象構件(NoteBook)角色:給出一個抽象接口,以規範準備接受附加責任的對象。
  • 具體構件(AppNotebook)角色:定義一個將要接收附加責任的類。
  • 裝飾(Dicorator)角色:持有一個構件(Component)對象的實例,並定義一個與抽象構件接口一致的接口。
  • 具體裝飾(Sticker和Peripherals)角色:負責給構件對象 ”貼上“附加的責任。

三、相關代碼:

1、抽象構件(NoteBook)角色

    /// <summary>
    /// 筆記本抽象類,即裝飾者模式中的抽象組件類
    /// </summary>
    public
abstract class NoteBook { public abstract void SayHello(); }

2、具體構件(AppNotebook)角色

    /// <summary>
    /// 聯想筆記本,即裝飾著模式中的具體組件類
    /// </summary>
    public class LenovoNoteBook : NoteBook
    {
        public override void SayHello()
        {
            Console.WriteLine("我是聯想筆記本
"); } }

3、裝飾(Dicorator)角色

    /// <summary>
    /// 裝飾抽象類,要讓裝飾完全取代抽象組件,所以必須繼承自NoteBook
    /// </summary>
    public abstract class Decorator:NoteBook
    {
        private NoteBook notebook;
        public Decorator(NoteBook n)
        {
            this.notebook = n;
        }
        public override void SayHello()
        {
            if(notebook!=null)
            {
                notebook.SayHello();
            }
        }
    }

4、具體裝飾(Sticker和Peripherals)角色

    /// <summary>
    /// 貼膜,即具體裝飾者
    /// </summary>
    public class Sticker : Decorator
    {
        public Sticker(NoteBook n) : base(n)
        {
        }
        public override void SayHello()
        {
            base.SayHello();
            //添加新行為
            AddSticker();
        }

        /// <summary>
        /// 新的行為方法
        /// </summary>
        public void AddSticker()
        {
            Console.WriteLine("給聯想筆記本貼膜");
        }
    }
    /// <summary>
    /// 外設,另一個具體裝飾者
    /// </summary>
    public class Peripherals : Decorator
    {
        public Peripherals(NoteBook n) : base(n)
        {
        }
        public override void SayHello()
        {
            base.SayHello();
            //添加新行為
            AddPeripherals();
        }

        /// <summary>
        /// 新的行為方法
        /// </summary>
        public void AddPeripherals()
        {
            Console.WriteLine("給聯想筆記本加外設");
        }
    }

5、調用

        static void Main(string[] args)
        {
            //創建聯想筆記本對象
            NoteBook notebook = new LenovoNoteBook();
            //擴展貼膜行為
            Decorator lenovowithsticker = new Sticker(notebook);
            lenovowithsticker.SayHello();
            Console.WriteLine("=======================");

            //擴展增加外設行為
            Decorator lenovowithperipherals = new Peripherals(notebook);
            lenovowithperipherals.SayHello();
            Console.WriteLine("=======================");

            //同時擴展貼膜和增加外設行為
            Sticker sticker = new Sticker(notebook);
            Peripherals peripherals = new Peripherals(sticker);
            peripherals.SayHello();
            Console.ReadKey();
        }

如果需要添加輔助扇熱風扇時,此時只需要添加一個繼承Decorator的輔助扇熱風扇類,從而,裝飾者模式擴展性也非常好。

四、使用場景:

  1. 需要擴展一個類的功能或給一個類增加附加責任。
  2. 需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。
  3. 需要增加由一些基本功能的排列組合而產生的非常大量的功能

五、總結:

優點

  • 裝飾這模式和繼承的目的都是擴展對象的功能,但裝飾者模式比繼承更靈活
  • 通過使用不同的具體裝飾類以及這些類的排列組合,設計師可以創造出很多不同行為的組合
  • 裝飾者模式有很好地可擴展性

缺點

  • 裝飾者模式會導致設計中出現許多小對象,如果過度使用,會讓程序變的更復雜。並且更多的對象會是的差錯變得困難,特別是這些對象看上去都很像。

C#設計模式——裝飾者模式