1. 程式人生 > >設計模式——裝飾模式

設計模式——裝飾模式

decorator text err span 方法 切換 rtu .text 指標

一、簡介

裝飾模式(Decorator)又名包裝器(Wrapper),屬於結構型模式的一種,采用遞歸的思想,用於包裝類,使其功能豐富。

例如:有一個統計圖表控件,可能需要有圖/表切換的功能(切換按鈕),也可能需要添加一個下拉框,用於過濾統計圖表某個指標,

這些附加的功能根據不同的應用場景而不同,此時可以考慮采用裝飾模式,動態為原始統計圖表對象添加功能。

二、類圖(引用GoF)

技術分享

Component是原型類,被裝飾的對象;

ConcreteComponet繼承於Component,具體原型類;

Decorator是裝飾基類,用於裝飾Component,繼承於Component,且擁有(關聯)一個Component對象;

ConcreteDecoratorA和ConcreteDecoratorB為Decorator的派生類。

三、例子

在實際應用中,可以靈活運用裝飾模式,可以沒有具體原型類,也可以沒有裝飾基類。

下面通過一組例子詳細介紹其用法。

1、裝飾原型類的方法,為方法添加功能(包含具體原型類和裝飾基類)

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

namespace 裝飾模式
{
    //=============================裝飾方法SetA()================================
/// <summary> /// 原型類 /// </summary> public class BaseObject0 { private string a; public virtual void SetA() { } } public class DrivedObject0 : BaseObject0 { public override void SetA() { base.SetA(); } }
/// <summary> /// 裝飾基類 /// </summary> public class DecorateBase0 : BaseObject0 { private BaseObject0 obj = null; public DecorateBase0(BaseObject0 boj) { this.obj = boj; } public override void SetA() { if (obj!=null) { obj.SetA(); } } } //============================================================= /// <summary> /// 裝飾子類A /// </summary> public class Adecorate0 : DecorateBase0 { public Adecorate0(BaseObject0 boj) : base(boj) { } public override void SetA() { base.SetA(); Console.WriteLine("Adecorate0" + System.Environment.NewLine); } } //============================================================ /// <summary> /// 裝飾子類B /// </summary> public class Bdecorate0 : DecorateBase0 { public Bdecorate0(BaseObject0 boj) : base(boj) { } public override void SetA() { base.SetA(); Console.WriteLine("Bdecorate0" + System.Environment.NewLine); } } }

調用:

Bdecorate0 bdecorate = new Bdecorate0(new Adecorate0(new BaseObject0()));
            bdecorate.SetA();
            Console.ReadKey();

結果:

技術分享

2、通過方法裝飾類的字段或屬性(不包含具體原型類和裝飾基類)

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

namespace 裝飾模式
{
    //=============================裝飾字段a================================
    /// <summary>
    /// 原型類
    /// </summary>
    public class BaseObject4
    {
        public string a;
        public virtual void SetA()
        {

        }
    }

    /// <summary>
    /// 裝飾基類
    /// </summary>
    public class DecorateBase4:BaseObject4
    {
        protected BaseObject4 obj = null;
        public DecorateBase4(BaseObject4 boj)
        {
            this.obj = boj;
        }
    }

    //=============================================================
    /// <summary>
    /// 裝飾子類A
    /// </summary>
    public class Adecorate4 : DecorateBase4
    {
        public Adecorate4(BaseObject4 boj)
            : base(boj)
        {
 
        }
        public override void SetA()
        {
            obj.SetA();
            a = obj.a + "Adecorate" + System.Environment.NewLine;
        }
    }

    //============================================================
    /// <summary>
    /// 裝飾子類B
    /// </summary>
    public class Bdecorate4 : DecorateBase4
    {
        public Bdecorate4(BaseObject4 boj)
            : base(boj)
        {
 
        }
        public override void SetA()
        {
            obj.SetA();//Adecorate4(obj)的a的值為"Adecorate"
            a = obj.a + "Bdecorate" + System.Environment.NewLine;
        }
    }
}

調用:

Bdecorate4 bdecorate = new Bdecorate4(new Adecorate4(new BaseObject4()));
            bdecorate.SetA();
            Console.WriteLine(bdecorate.a);
            Console.ReadKey();

效果同上

3、裝飾方法(包含裝飾基類,不包含具體原型類)

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

namespace 裝飾模式
{
    /// <summary>
    /// 原型類
    /// </summary>
   public class BaseObject
    {
       private string a;
       public virtual string GetA()
       {
           return a;
       }
    }

    /// <summary>
    /// 裝飾基類
    /// </summary>
   public class decorator : BaseObject
   {
       BaseObject obj = null;
       public decorator(BaseObject bojPara)
       {
           this.obj = bojPara;
       }

       public override string GetA()
       {
           return obj.GetA();
       }
   }

    /// <summary>
    /// 裝飾子類A
    /// </summary>
   public class Adecorate : decorator
   {
       public Adecorate(BaseObject boj)
           :base(boj)
       {

       }
       public override string GetA()
       {
           return base.GetA() + "Adecorate";
       } 
   }

   /// <summary>
   /// 裝飾子類B
   /// </summary>
   public class Bdecorate : decorator
   {
       public Bdecorate(BaseObject boj)
           : base(boj)
       {

       }
       public override string GetA()
       {
           return base.GetA() + "Bdecorate";
       }
   }

}

調用:

Bdecorate bdecorate = new Bdecorate(new Adecorate(new BaseObject()));
            Console.WriteLine(bdecorate.GetA());            
            Console.ReadKey(); 

效果同上

4、裝飾方法(不包含裝飾基類和具體原型類)

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

namespace 裝飾模式
{

    /// <summary>
    /// 原型類
    /// </summary>
    public class BaseObject2
    {
        private string a;
        public virtual string GetA()
        {
            return a;
        }
    }


    /// <summary>
    /// 裝飾類A
    /// </summary>
    public class Adecorate2:BaseObject2 
    {
        BaseObject2 obj = null;
        public Adecorate2(BaseObject2 boj)
        {
            this.obj = boj;
        }

        public override string GetA()
        {
            return obj.GetA() + "Adecorate" + System.Environment.NewLine;
        }
    }

    /// <summary>
    /// 裝飾類B
    /// </summary>
    public class Bdecorate2 : BaseObject2 
    {
        BaseObject2 obj = null;
        public Bdecorate2(BaseObject2 boj)
        {
            this.obj = boj;
        }

        public override string GetA()
        {
            return obj.GetA() + "Bdecorate" + System.Environment.NewLine;
        }
    }

}

調用:

 Bdecorate2 bdecorate = new Bdecorate2(new Adecorate2(new BaseObject2()));
            Console.WriteLine(bdecorate.GetA());
            Console.ReadKey(); 

效果同上。.

5、通過方法裝飾字段或屬性(無裝飾基類和具體原型類)

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

namespace 裝飾模式
{

    
    /// <summary>
    /// 原型類
    /// </summary>
    public class BaseObject3
    {
        public string a;
        public virtual void SetA()
        {
            
        }
    }

    //=============================================================
    /// <summary>
    /// 裝飾類A
    /// </summary>
    public class Adecorate3 : BaseObject3
    {
        BaseObject3 obj = null;
        public Adecorate3(BaseObject3 boj)
        {
            this.obj = boj;
            
        }

        public override void SetA()
        {            
             obj.SetA();
             a = obj.a + "Adecorate" + System.Environment.NewLine;
        }
    }

    //============================================================
    /// <summary>
    /// 裝飾類B
    /// </summary>
    public class Bdecorate3 : BaseObject3
    {
        BaseObject3 obj = null;        
        public Bdecorate3(BaseObject3 boj)
        {
            this.obj = boj;
        }

        public override void SetA()
        {
            obj.SetA();//Adecorate3(obj)的a的值為"Adecorate"
            a=obj.a + "Bdecorate" + System.Environment.NewLine;
        }
    }
}

調用:

Bdecorate3 bdecorate = new Bdecorate3(new Adecorate3(new BaseObject3()));
            bdecorate.SetA();
            Console.WriteLine(bdecorate.a);
            Console.ReadKey();

方法同上。

設計模式——裝飾模式