天天看點

大話設計模式:裝飾模式

一、什麼是裝飾模式

給對象動态添加職責
           

裝飾模式像是一場大型職責擴充會,在不同的時間你需要具備不同的職責内容,一你可以獲得這些職責,二你可以放下這些職責.就增加功能來說,裝飾模式比子類更靈活.是為對象已有功能添加一些其他功能的方式.用戶端可以有選擇的按自己的順序裝飾對象.

UML圖
           
大話設計模式:裝飾模式

二、适用場景

當一個對象的一些職責或功能不必一直存在,而且是能很靈活的調整的時候,就可以考慮這個裝飾模式,比如那種單局獲得的回到主菜單就丢失的類型,就可以在關卡裡面獲得的道具技能都采用裝飾模式,當回到主界面就又恢複原對象 了,除了那些不必脫掉的功能.裝飾這個詞還是很貼切的,就像你穿衣服,你不會依賴于某件衣服,你想穿也行不穿也行.

當系統需要新功能的時候,是向舊的類中添加新代碼,還是用這些新加的代碼裝飾原有的類.如果新加入的東西僅僅是為了滿足一些隻在某種特定情況下才會執行的特殊行為的需要,那裝飾模式就提供了一個非常好的解決方案,它把每個要裝飾的功能放在單獨的類中,并讓這個類包裝它所要裝飾的對象.

三、優缺點

優點

裝飾模式的好處就在于職責不是鎖死的,能靈活調整.

對比于簡單繼承能避免功能繁瑣的子類.把裝飾功能從類中剔除,這樣可以簡化原有的類.

可以去除相關類中重複的裝飾邏輯.

缺點

存在特定的使用條件,如果是長存的功能,使用裝飾者反倒增加了類的數量.

裝飾者是針對抽象元件程式設計Component.

種比繼承更加靈活機動的特性,也同時意味着更加多的複雜性。

裝扮是單一個不可重複裝扮相同的對象功能,你可以重新執行個體一個.

四、大話中的例子

小菜裝扮靓裝的例子,小菜有許多種穿搭風格可選擇,穿搭的順序也是能随心替換的, 讓小菜有一個抽象的裝扮方法,讓裝飾者抽象類繼承小菜,并能獲得小菜進行關聯,再重寫裝扮方法,把獲得的小菜放進來.具體裝扮類繼承抽象裝扮類,進行一些自己的特性裝扮.

五、我的例子

using System;

namespace DecoratorMode
{
    class Program
    {
        static void Main(string[] args)
        {
            Naruto naruto = new Naruto("鳴人");
            Xigua xigua = new Xigua();
            Boluo boluo = new Boluo();
            Niunai niunai = new Niunai();
            Juanzhou juanzhou = new Juanzhou();
            xigua.SetCompoment(naruto);
            boluo.SetCompoment(xigua);
            niunai.SetCompoment(boluo);
            juanzhou.SetCompoment(niunai);
            juanzhou.GoShopping();
          
        }
    }

    public abstract class Compoment
    {
        public int price;
        public abstract void GoShopping();
    }

    public class Naruto : Compoment
    {
        string name;

        public Naruto(string name)
        {
            price = 30;
            this.name = name;
        }
        public override void GoShopping()
        {
            Console.WriteLine("總共花了:" + price);
            Console.WriteLine("{0}吃了拉面之後買了:", name);
        }
    }

    public class Shop : Compoment
    {
        public Compoment comp;
        public void SetCompoment(Compoment compoment)
        {
            comp = compoment;
        }
        public override void GoShopping()
        {
            if (comp != null)
            {
                comp.price += price;//這裡更像是一個遞歸,一層一層往裡找
                comp.GoShopping();
            }
        }
    }

    public class Xigua : Shop
    {
        public Xigua()
        {
            price = 15;
        }
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("西瓜");
        }
    }

    public class Boluo : Shop
    {
        public Boluo()
        {
            price = 5;
        }
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("鳳梨");
        }
    }

    public class Niunai : Shop
    {
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("牛奶");
        }
    }
    public class Juanzhou : Shop
    {
        public Juanzhou()
        {
            price = 1000;
        }
        public override void GoShopping()
        {

            base.GoShopping();
            Console.WriteLine("卷軸");
        }
    }
    public class Paomian : Shop
    {
        public override void GoShopping()
        {
            base.GoShopping();
            Console.WriteLine("泡面");
        }
    }
}

           
運作結果
           
大話設計模式:裝飾模式

PS: 還有些有趣的例子,比如下火鍋,先有一個鍋底,然後配菜都是自選的,怎麼下也是随意的.還比如買奶茶,奶茶有基礎款,你也可以加珍珠,加糖,等. 感覺裝飾者模式實質上是一個遞歸的堆棧,一層套一層.每一層就是一個裝飾.

繼續閱讀