淺談GoF23設計模式-“Decorator”模式

前言

可能對設計模式學習尚淺,所以每次回味“Decorator”模式時都覺的這是一個天才的設計模式(可能僅對于我自己來講),所以首先我們先探討一下使用“Decorator”模式的動機:當我們過度地使用繼承來擴展對象的功能時,由于繼承為類型引入的靜態(tài)特質(zhì),使得這種擴展方式缺乏靈活性,并且隨著子類的增多(擴展功能的增多),各種子類的組合會導致更多子類的膨脹,因此為了避免這種膨脹我們引入了“Decorator”(裝飾)模式。
使用手法:裝飾類和被裝飾類都繼承同一接口,被裝飾類的對象傳入裝飾類的構造函數(shù)中當作參數(shù),在執(zhí)行被裝飾業(yè)務之前加入裝飾類業(yè)務邏輯即可!

1.“Decorator”模式定義:動態(tài)地給一個對象增加一些額外地職責。就增加功能而言,Decorator模式比生成子類更靈活。

Decorator.png

2.“Decorator”模式要點:

1.)通過采用組合,而非繼承地手法,Decorator模式實現(xiàn)了在運動時動態(tài)地擴展對象功能地能力,而且可以根據(jù)需要擴展多個功能。避免了單獨使用繼承帶來地“靈活性差”和“多子類衍生問題”。
2.)上圖中的Component類在Decorator模式中充當抽象接口的角色,不應該去實現(xiàn)具體的行為。而且Decorator類對于Component類應該透明,換言之Component類無需知道Decorator類,Decorator類是從外部來擴展Component類的功能。
3.)Decorator類在接口上表現(xiàn)為is-a Component的繼承關系,即Decorator類繼承了Component類所具有的接口。但在實現(xiàn)上又表現(xiàn)為has-a Component組合關系,即Decorator類又使用了另一個Component類。我們可以使用一個或多個Decorator對象來“裝飾”一個Component對象,且裝飾后的對象仍然是一個Component對象。
4.)Decorator模式并非解決“多子類衍生的多繼承”問題,Decorator模式應用的要點在于解決“主體在多個方向上的擴展功能”

下面我們看一個如何使用裝飾給坦克擴展“衛(wèi)星定位功能”和“降噪功能”

//抽象類,相當于上圖中的Componen
  public abstract class Tank
{
        public abstract void Shot();

        public abstract void Run();
 }
//實現(xiàn)類,相當于上圖的“ConcreteComponent”
public class T50 : Tank
{
        public override void Run()
        {
            throw new NotImplementedException();
        }

        public override void Shot()
        {
            throw new NotImplementedException();
        }
}
//Decorator裝飾
 public abstract class Decorator:Tank
    {
        Tank tank;

        public Decorator(Tank tank)
        {
            this.tank = tank;
        }

        public override void Shot()
        {
            throw new NotImplementedException();
        }

        public override void Run()
        {
            throw new NotImplementedException();
        }
    }
    /// <summary>
    /// 添加衛(wèi)星定位功能
    /// </summary>
    public class DecoratorA : Decorator
    {
        public DecoratorA(Tank tank) : base(tank)
        {
        } 
        public override void Run()
        {
            //衛(wèi)星定位邏輯代碼
            //...
            base.Run();
        }
        public override void Shot()
        {
            //衛(wèi)星定位邏輯代碼
            //...
            base.Shot();
        }
    }

    /// <summary>
    /// 添加降噪功能
    /// </summary>
    public class DecoratorB: Decorator
    {
        public DecoratorB(Tank tank) : base(tank)
        {
        }
        public override void Run()
        {
            //降噪功能邏輯代碼
            //...
            base.Run();
        }
        public override void Shot()
        {
            //降噪功能邏輯代碼
            //...
            base.Shot();
        }
    }
//客戶程序調(diào)用
 public class App
    {
        public static void Main(string[] args)
        {
            T50 tank = new T50();
            //T50實現(xiàn)衛(wèi)星定位功能
            DecoratorA da = new DecoratorA(tank);
            //T50實現(xiàn)降噪功能
            DecoratorB db = new DecoratorB(da); 
        }
    }

在.Net框架中“Decorator”模式也經(jīng)常使用,例如:
Stream下“BufferedStream”和“CryptoStream”為裝飾對象,而“FileStream”、“NetworkStream”、“MemoryStream”為具體實現(xiàn)類。


Stream.png
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容