閱讀541 返回首頁    go 阿裏雲 go 技術社區[雲棲]


設計模式之裝飾模式

          裝飾模式,動態的給一個對象添加一些額外的職責,就增加功能而言,裝飾模式比生成子類更為靈活。這種模式可以有效的將類的核心職責和裝飾功能區分開來。

        設計原則:

         1、多用組合,少用繼承

            利用繼承設計子類的行為,是在編譯時靜態決定的,而且所有的子類都會繼承到相同的行為。然而,如果能夠利用組合的做法擴展對象的行為,就可以在運行時動態地進行擴展。

           2、類的設計應對擴展開放,對修改關閉。

         要點:

                       1. 裝飾者和被裝飾對象有相同的超類型。

                   2. 可以用一個或多個裝飾者包裝一個對象。

                   3. 裝飾者可以在所委托被裝飾者的行為之前或之後,加上自己的行為,以達到特定的目的。

                   4. 對象可以在任何時候被裝飾,所以可以在運行時動態的,不限量的用你喜歡的裝飾者來裝飾對象。

                   5. 裝飾模式中使用繼承的關鍵是想達到裝飾者和被裝飾對象的類型匹配,而不是獲得其行為。

                   6. 裝飾者一般對組件的客戶是透明的,除非客戶程序依賴於組件的具體類型。在實際項目中可以根據需要為裝飾者添加新的行為,做到“半透明”裝飾者。

                   7. 適配器模式的用意是改變對象的接口而不一定改變對象的性能,而裝飾模式的用意是保持接口並增加對象的職責。

            結構圖:


             適用性:

                 1、需要擴展一個類的功能,或給一個類添加附加職責。
                 2、動態的給一個對象添加功能,這些功能可以再動態的撤銷。
                 3、當不能采用生成子類的方法進行擴充時。
             例子:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 裝飾模式
{
    class Program
    {
        static void Main(string[] args)
        {
            Person WD = new Person("dd");

            Console.WriteLine("\n第一種裝扮");

            Sneakers pqx = new Sneakers();
            BigTrouser kk = new BigTrouser();
            TShirts dtx = new TShirts();
            pqx.Decorate(WD);
            kk.Decorate(pqx);
            dtx.Decorate(kk);

            dtx.Show();

            Console.WriteLine("\n第二種裝飾");

            LeatherShoes px = new LeatherShoes();
            Tie ld = new Tie();
            Suit xz = new Suit();

            px.Decorate(WD);
            ld.Decorate(px);
            xz.Decorate(ld);
            xz.Show();

            Console.Read();
        }
        class Person//具體定義了對象,相當於concreteComponent
        {
            public Person()
            { }
            private  string name;
            public Person (string name)
            {
                this.name = name;
            }
            public virtual void Show()
            {
                Console.WriteLine("裝飾的{0}",name);
            }
        }
        class Finery:Person //裝飾抽象類,相當於decorator
        {
            protected Person component;
            public void Decorate(Person component)
            {
                this.component = component;
            }
            public override void Show()
            {
                if (component != null )
                {
                    component.Show();
                }
            }

        }
        class TShirts:Finery
        {
            public override void Show()
            {
                Console.WriteLine("大體恤");
                base.Show();
            }
        }
        class BigTrouser:Finery
        {
            public override void Show()
            {
                Console.WriteLine("垮褲");
                base.Show();
            }
        }
        class Sneakers:Finery 
        {
            public override void Show()
            {
                Console.WriteLine("破球鞋");
                base.Show();
            }
        }
        class Suit : Finery
        {
            public override void Show()
            {
                Console.WriteLine("西裝");
                base.Show();
            }
        }
        class Tie : Finery
        {
            public override void Show()
            {
                Console.WriteLine("領帶");
                base.Show();
            }
        }
        class LeatherShoes : Finery
        {
            public override void Show()
            {
                Console.WriteLine("皮鞋");
                base.Show();
            }
        }

    }
}
           裝飾模式在此例中產生的效果就是衣服是按順序穿的,類的核心職責和裝飾功能是分開的,使得功能的擴展、應用更加靈活。


                 


最後更新:2017-04-03 12:55:04

  上一篇:go Android Studio 中提示 Private field 'mType' is assigned but never accessed 的原因
  下一篇:go Win7 文件夾無法賦權限