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

ZeroWM發表於2014-05-30

一、概念

裝飾模式(Decorator)動態地給一個物件新增一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。


二、UML圖


Component(被裝飾物件基類): 定義物件的介面,可以給這些物件動態增加職責;

ConcreteComponent(具體被裝飾的物件): 定義具體的物件,Decorator可以給它增加額外的職責;

Decorator(裝飾者抽象類): 維護一個指向Component例項的引用,並且定義了與Component一致的介面;

ConcreteDecorator(具體裝飾者): 具體的裝飾物件,給內部持有的具體被裝飾物件增加具體的職責。




三、例項解析

  有一句很有道理話,想必大家都聽過:沒有醜女人,只有懶女人。有一張保養的很好的臉的確能給初次印象加不少的分數。我想大部分女生都知道,每個宿舍都有幾個愛臭美的女生,早上起的特別早,在臉上抹了一層又一層,想知道是怎麼個順序嗎?下面讓我們進入這個小例子:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication9
{

    class Program//客戶端程式碼
    {
        static void Main(string[] args)
        {
            Person xm = new Person("小美");
            Console.WriteLine("\n 基礎護膚順序:");

            Water shui = new Water();
            Lotion ruye = new Lotion();
            Sunscreen fangshai = new Sunscreen();
            Isolation geli = new Isolation();

            //擦護膚品的過程
            geli.Decorate(xm);
            fangshai.Decorate(geli);
            ruye.Decorate(fangshai );
            shui.Decorate(ruye);
            shui.Show();

        }
    }

    //Person類(ConcreteComponent)
    class Person
    {
        public Person()
        { }
        public string name;
        public Person(string name)
        {
            this.name = name;
        }
        public virtual void Show()
        {
            Console.WriteLine("的{0}",name );

        }
    }

    //保養品類(Decorator)
    class MakeUp : Person
    {
        protected Person component;
        public void Decorate(Person component)
        {
            this.component = component;

        }
        public override void Show()
        {
            if (component !=null)
            {
                component.Show();
            } 
        }
        
    
    }


    //具體保養品類(ConcreteDecorator)
    class Water : MakeUp
    {
        public override void Show()
        {
            Console.Write("水 ");
            base.Show();
        }
    }

    class Lotion : MakeUp
    {
        public override void Show()
        {
            Console.Write("乳液 ");
            base.Show();
        }
    }
    class Sunscreen : MakeUp
    {
        public override void Show()
        {
            Console.Write("防曬 ");
            base.Show();
        }
    }
    class Isolation : MakeUp
    {
        public override void Show()
        {
            Console.Write("隔離 ");
            base.Show();
        }
    }

}

執行結果:



  該例子中運用到了裝飾模式,其中特別要注意把所需的功能按照正確的順序串聯起來進行控制,比如例子中這些保養品的順序是按照分子大小的順序來塗抹的,小分子的先抹,大分子的後抹,如果順序顛倒,保溼的進不去,隔離、防曬可能會傷及皮膚。



四、總結

裝飾模式的優點:

1.它把每個要裝飾的功能放在單獨的類中,簡化了原有類,並讓這個類包裝它所要裝飾的物件。因此,當需要執行特殊行為時,客戶端程式碼就可以在執行時根據需要有選擇的,按順序的使用裝飾功能包裝物件。

2.有效的把類的核心職責裝飾功能區分開了。而且可以去除相關類中重複的裝飾邏輯。

缺點:

1.裝飾鏈不過長,否則會影響效率。

2.通過繼承關係建立的關係是脆弱的,如果基類變,勢必會影響物件的內部;組合建立的關係只會影響到被裝飾物件的外部特徵。

3.只有在必要的的時候使用裝飾模式,否則會提高程式的複雜性,增加系統維護難度。


聯絡 策略模式:

裝飾模式跟策略模式有很相似的一點就是簡化功能,策略模式簡化了客戶端的程式碼,將業務邏輯和介面邏輯分開,裝飾模式簡化了類,將類中的裝飾功能從類中搬移去除。


啟發:

管理,要分工明確,核心職責突出,不能所有的活都幹,要明確大方向,擁有全域性觀。




相關文章