裝飾者模式 - OK

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

    裝飾者模式隱含的是經過一條條裝飾鏈去實現具體對象,每一條裝飾鏈都始於一個Componet對象,每一個裝飾者對象後面緊跟着另外一個裝飾者對象,而對象鏈終於ConcreteComponet對象。html

  用粗略的話講:裝飾模式就是爲已有功能動態地添加更多功能的一種方式。java

  何爲動態。好比打折策略。3折後再減30元再打8折,git

  UML圖以下:設計模式

    

  Component是定義一個對象接口,能夠給這些對象動態地添加職責。ConcreteComponent是定義了一個具體的對象,也能夠給這個對象添加一些職責。Decorator,裝飾着抽象類,繼承了Component從外類來擴展Component類的功能,但對於Component來講,就無需知道Decorator的存在的。至於ConcreteDecorator就是具體的裝飾對象。起到給Component添加職責的功能。ide

  實現代碼示例:post

  裝飾模式是利用SetComponent來對對象進行包裝的。這樣每一個裝飾對象的實現就和如何使用這個對象分離開了。每一個裝飾對象只關心本身的功能,不須要關心如何被添加到對象鏈當中。this

  示例:spa

複製代碼
namespace 裝飾者模式
{
    class Program
    {
        static void Main(string[] args)
        {
            ConcreateComponent c = new ConcreateComponent();
            ConcreteDecorator眉毛 d1 = new ConcreteDecorator眉毛();
            ConcreteDecorator頭髮 d2 = new ConcreteDecorator頭髮();

            d1.SetComponent(c);     //d1裏面放入c,是爲了調用原始c的 捕獲素顏美女
            d2.SetComponent(d1);    //d1是畫過眉毛的
            d2.Operation();

            Console.ReadKey();
        }
    }  

    abstract class Component
    {
        public abstract void Operation();
    }

    class ConcreateComponent : Component
    {
        //原始內容,具體裝飾類都會調用一次
        public override void Operation()
        {
            Console.WriteLine("捕獲素顏美女一個!");
        }
    }

    abstract class Decorator : Component
    {
        //裏面放一個父接口
        protected Component component;

        public void SetComponent(Component component)   //設置Component
        {
            this.component = component;
        }

        public override void Operation()    //用接收到的Component的Operation方法來重寫父Component接口的Operation方法
        {
            if (component != null)
            {
                component.Operation();
            }
        }
    }

    class ConcreteDecorator眉毛 : Decorator
    {
        private string addedState;      //表明畫眉毛的實際操做

        public override void Operation()
        {
            base.Operation();           //素顏美女(原始內容)
            Console.WriteLine("幫美女畫畫眉!");
            addedState = "眉毛漂亮了!";    //實際裝飾內容
        }
    }

    class ConcreteDecorator頭髮 : Decorator
    {
        public override void Operation()
        {
            base.Operation();           //原始內容
            Console.WriteLine("幫美女梳梳頭!");
            AddedBehavior();            //實際裝飾內容
        }

        private void AddedBehavior()    //本類獨有的方法,以區別於ConcrateDecoratorA
        {
            Console.WriteLine("頭髮變精神了!");
        }
    }
}
複製代碼

  這個示例寫得不錯,基本上掌握了裝飾者的做用。設計

  

  裝飾者模式的應用場景:

  1. 想透明而且動態地給對象增長新的職責的時候。
  2. 給對象增長的職責,在將來存在增長或減小可能。
  3. 用繼承擴展功能不太現實的狀況下,應該考慮用組合的方式。

  裝飾者模式的優勢:

  1. 經過組合而非繼承的方式,實現了動態擴展對象的功能的能力。
  2. 有效避免了使用繼承的方式擴展對象功能而帶來的靈活性差,子類無限制擴張的問題。
  3. 充分利用了繼承和組合的長處和短處,在靈活性和擴展性之間找到完美的平衡點。
  4. 裝飾者和被裝飾者之間雖然都是同一類型,可是它們彼此是徹底獨立並能夠各自獨立任意改變的。
  5. 遵照大部分GRASP原則和經常使用設計原則,高內聚、低偶合。

  裝飾者模式的缺點:

  1. 裝飾鏈不能過長,不然會影響效率。
  2. 由於全部對象都是繼承於Component,因此若是Component內部結構發生改變,則不可避免地影響全部子類(裝飾者和被裝飾者),也就是說,經過繼承創建的關係老是脆弱地,若是基類改變,勢必影響對象的內部,而經過組合(Decoator HAS A Component)創建的關係只會影響被裝飾對象的外部特徵。
  3. 只在必要的時候使用裝飾者模式,不然會提升程序的複雜性,增長系統維護難度。
 
 
分類: 設計模式
 
0
0
 
(請您對文章作出評價)
 
« 上一篇: 策略模式 - OK
» 下一篇: 代理模式 - OK
相關文章
相關標籤/搜索