重看Decorator Pattern,聯想到Delegate傳遞及Flags Enum--歡迎拍磚!

  話說裝飾模式(Decorator)的動機是「動態地給一個對象添加一些額外的職責。就增長功能來講,Decorator模式相比生成子類更爲靈活。[GOF 《設計模式》]」。再次學到該模式,有感,聯想到Delegate和Flags Enum。Delegate也可實如今已有功能上動態添加新功能,有點」裝飾「的意圖,Flags Enum能夠進行組合使用。若是對裝飾模式不熟悉,請移步大神博文http://terrylee.cnblogs.com/archive/2006/03/01/340592.html。本文描述該模式的相關思考,不正之處,請大神指點拍磚!謝謝html

  該模式的UML圖: ,Decorator抽象,既繼承Component又組合引用Component,爲何須要這樣呢?從該模式的具體代碼看到,裝飾之上能夠繼續裝飾,故須要引用一個裝飾,爲何有須要繼承呢,感受裝飾須要一個抽象吧。設計模式

  如今來假設一個場景,有一個現有的對象,以下:app

public class Component
    {
        public void Operation(string msg)
        {
            Console.WriteLine("Compent.Operation。hi,:"+msg);
        }
    }

 該操做不是可override的,那怎麼使用裝飾模式來擴展新功能呢?這裏給出裝飾模式的「變形代碼」ide

    public class ComponentWrapper
    {
        public virtual void Operation(string msg)
        {
            Component m_Component = new Component();
            m_Component.Operation(msg);
        }
    }

    public class ComponentWrapper1 : ComponentWrapper
    {
        private ComponentWrapper m_decorator;
        public ComponentWrapper1(ComponentWrapper decorator)
        {
            m_decorator = decorator;
        }
        public override void Operation(string msg)
        {
            m_decorator.Operation(msg);
            Add(msg);
        }
        public static void Add(string msg)
        {
            Console.WriteLine("ComponentWrapper1 added");
        }
    }

    public class ComponentWrapper2 : ComponentWrapper
    {
        private ComponentWrapper m_decorator;
        public ComponentWrapper2(ComponentWrapper decorator)
        {
            m_decorator = decorator;
        }
        public override void Operation(string msg)
        {
            m_decorator.Operation(msg);
            Add(msg);
        }
        public static void Add(string msg)
        {
            Console.WriteLine("ComponentWrapper2 added");
        }
    }
//調用代碼            
ComponentWrapper d = new ComponentWrapper();//未裝飾 ComponentWrapper d1 = new ComponentWrapper1(d);//裝飾上功能1 ComponentWrapper d2 = new ComponentWrapper2(d1);//裝飾上功能2 d2.Operation("stevey");

上面代碼中,ComponentWrapper 做爲裝飾的基類,對已有功能進行包裝,在裝飾1中繼承裝飾基類又包含一個裝飾。可能說包裝感受更形象一點,一層一層的包裝,或者說人穿的衣服也是一層一層的,哈哈。能夠看到,一個裝飾對象就做爲一個」功能集「總體,其實是一個引用裝飾鏈,調用依次傳遞到頂端。由此聯想到,功能也能夠追加,功能也能夠作成像鏈式依次執傳遞。遵循上面場景的方法契約,因而就憑着感受寫出以下code:this

    public static class ComponentExtension
    {
        /// <summary>
        /// 在已有操做以後加上新操做
        /// </summary>
        /// <param name="action">原操做</param>
        /// <param name="otherAction">新操做</param>
        /// <returns></returns>
        public static Action<string> After(this Action<string> action,Action<string> otherAction)
        {
            return (msg) => {
                action(msg);
                otherAction(msg);
            };
        }

        public static Action<string> Before(this Action<string> action, Action<string> otherAction)
        {
            return (msg) =>
            {
                otherAction(msg);
                action(msg);
            };
        }
    }

調用代碼:spa

//使用delegate裝飾新功能
            Action<string> action = new Component().Operation;
            Action<string> wrapper1 = action.After(ComponentWrapper1.Add);//裝飾上功能1
            Action<string> wrapper2 = wrapper1.After((msg) =>//裝飾上功能2
            {
                Console.WriteLine("wrapper2 added");
            });
            wrapper2("hello");
            Console.WriteLine("*****************************");
            //
            Action<string> wrapper3 = wrapper1.After(wrapper2);
            wrapper3("(原功能+功能1)+{(原功能+功能1)+裝飾上功能2}");//在已有的裝飾總體上加上另外一個裝飾

上面的代碼能夠鏈式,其餘不解釋了,代碼是最直接的意思表達,在一個功能上繼續包裝一個功能,獲得的就是一個裝飾,能夠做爲總體,繼續裝飾。。。貌似比模式輕量級點不。設計

  標記枚舉,也有點」裝飾「的味道,MSDN上的代碼:code

[Flags]
    enum Days2
    {
        None = 0x0,
        Sunday = 0x1,
        Monday = 0x2,
        Tuesday = 0x4,
        Wednesday = 0x8,
        Thursday = 0x10,
        Friday = 0x20,
        Saturday = 0x40
    }
//Flags Enum
            // Initialize with two flags using bitwise OR.
            var meetingDays = Days2.Tuesday | Days2.Thursday;

            // Set an additional flag using bitwise OR.
            meetingDays = meetingDays | Days2.Friday;

            Console.WriteLine("Meeting days are {0}", meetingDays);
            // Output: Meeting days are Tuesday, Thursday, Friday

            // Remove a flag using bitwise XOR.
            meetingDays = meetingDays ^ Days2.Tuesday;
            Console.WriteLine("Meeting days are {0}", meetingDays);
            // Output: Meeting days are Thursday, Friday

 

  就寫到這裏吧,感受有點語無倫次,不在狀態,你們就將就看吧。算是一點裝飾模式的讀後感,歡迎你們討論,不正之處,還請指出,謝謝!htm

相關文章
相關標籤/搜索