1. 程式人生 > >【設計模式】——裝飾模式

【設計模式】——裝飾模式

【裝飾模式】

裝飾模式是利用component來對物件進行包裝。每個裝飾物件的實現就和如何使用這個物件分離開了,每個裝飾物件只關心自己的功能,不需要關心如何被新增到物件鏈當中

【介紹】

  • 主要解決:一般的,我們為了拓展一個類經常使用繼承方法實現,由於繼承為類引入靜態特徵,並且隨著擴充套件共能的增多,子類會很多

  • 何時使用:在不想增加很多子類的情況下擴充套件類

  • 如何解決:將具體功能職責劃分,同時繼承裝飾模式

  • 關鍵程式碼:

            1、component類充當抽象角色,不應該具體實現

            2、修飾類引用和繼承component類,具體拓展類重寫父類方法

  • 優點:裝飾類和被裝飾類可以獨立發展,不會相互耦合,裝飾模式是繼承一個替代模式,裝飾模式可以動態擴充套件一個實現類的功能

  • 缺點:多層裝飾比較複雜

【實現】

Comonent是定義一個物件介面,可以給這些物件動態地新增職責。ConcreteComponent是定義了一個具體的物件,也可以給這個物件新增一些職責。Decorator,裝飾抽象類,繼承Component從外來來擴充套件conponent類的功能,但對於Component來說,是無需知道Decorator的存在的。至於ConcreteDecorator就是具體的裝飾物件,起到給Component新增職責的功能

一個更容易理解的例項

裝飾模式為已有類動態附加額外的功能就像是LoL和王者榮耀遊戲中,英雄的升級一樣。每次英雄升級都會附加一個額外技能點去學習技能。具體的英雄就是Concretecomponent,技能欄就是裝飾器Decorator,每個技能就是ConcreteDecorator

步驟一:建立一個介面

abstract class Component

    {

        public abstract void Operation();

    }

步驟二:建立實現介面的實體類

//ConcreateComponent

class ConcreateComponent :Component

    {

        public override void Operation()

        {

            Console.WriteLine("具體物件的操作");

        }

    }

步驟三:建立component介面的抽象裝飾類

abstract class Decorator:Component

    {

        protected Component component;

        public void SetComponent(Component component)//設定Component

        {

            this.component = component;

        }

        public override void Operation()

        {

            if (component !=null)

            {

                component.Operation();

            }

        }

    }

步驟四:建立具體的裝飾物件類

abstract class Decorator:Component

    {

        protected Component component;

        public void SetComponent(Component component)//設定Component

        {

            this.component = component;

        }

        public override void Operation()

        {

            if (component !=null)

            {

                component.Operation();

            }

        }

    }

       class ConcreteDecoratorA:Decorator

    {

        private string addedState;//本類獨有功能,以區別於ConcreteDecoratorB

        public override void Operation()

        {

            base.Operation();//首先執行原component的operation(),再執行本類的功能,,如addedstate,相當於對原component進行了裝飾

            addedState = "new state";

            Console.WriteLine("具體裝飾物件A的操作");

        }

    }

    class ConcreteDecoratorB : Decorator

    {

      

        public override void Operation()

        {

            base.Operation();

            AddedBehavior();

            Console.WriteLine("具體裝飾物件B的操作");

        }

        private void AddedBehavior()//本類獨有的方法

        {



        }

    }

步驟五:客戶端程式碼

static void Main(string[] args)

        {

            ConcreateComponent c = new ConcreateComponent();

            ConcreteDecoratorA d1 = new ConcreteDecoratorA();

            ConcreteDecoratorB d2 = new ConcreteDecoratorB();



            d1.SetComponent(c);

            d2.SetComponent(d1);

            d2.Operation();

            //裝飾的方法是:首先用concretecomponent例項化物件c,然後用concreteDecoratorA的例項化物件d1來包裝c

            //再用ConcreteDecoratorB的物件d2來包裝d1,最終執行d2的operation()

            Console.Read();

        }

【總結】

裝飾模式是為已有功能動態地新增更多功能的一種方式。當系統需要新功能的時候,是向舊的類中新增新的程式碼,這些新加的程式碼通常裝飾了原有類的核心職責或主要行為,在主類中加入了新的欄位,新的方法和新的邏輯,從而增加了主類的複雜度,這些新加入的東西僅僅是為了滿足一些只在某種特定情況下才會執行的特殊行為的需求。