裝飾模式

裝飾模式

裝飾模式是一種用於代替繼承的技術,達到無需定義子類卻能夠給對象動態增長職責的效果。讓對象之間的繼承關係轉變爲關聯關係。算法

裝飾模式能夠在不改變已有對象自己的功能的基礎上給對象增長額外的新職責,比如平常生活中的照片,能夠給照片使用相框,使之具備防潮的功能,可是這樣並無改變照片自己,這即是裝飾模式。ide

裝飾模式的結構

image.png

  • Component(抽象構件):具體構件和抽象裝飾類的父類,聲明瞭具體構件中所需的業務方法,引入該抽象層能夠將未被裝飾的對象和裝飾後的對象統一處理。
  • SpecificComponent(具體構件):派生自抽象構件,用於定義具體的構件對象,實現了抽象構件中的方法,裝飾類能夠給它增長額外的職責。
  • Decorator(抽象裝飾類):派生自抽象構件,用於給具體構件增長職責,一般具體職責實如今抽象裝飾類的子類中。內部維護一個抽象構件對象的引用,經過這個引用能夠調用裝飾以前對象的方法,並經過其子類擴展該方法達到裝飾的目的。
  • SpecificDecorator(具體裝飾類):派生自抽象裝飾類,負責給構件添加新職責。每一個具體裝飾類都定義了新的行爲,它能夠調用在抽象裝飾類中的方法,也能夠增長新的方法。

裝飾模式的實現

  • 抽象構件
abstract class Component
{
    public abstract void Operation();
}
  • 具體構件(一般只實現基本功能,複雜功能經過裝飾類擴展)
class SpecificComponent : Component
{
    public override void Operation()
    {
        //實現基本功能
    }
}
  • 抽象裝飾類(核心)
class Decorator : Component
{
    private Component m_Component;

    public Decorator(Component component)
    {
        this.m_Component = component;
    }

    public override void Operation()
    {
        //調用原有業務的方法,並未真正裝飾,具體裝飾交給子類
        this.m_Component.Operation();
    }
}
  • 具體裝飾類
class SpecificDecorator : Decorator
{
    public SpecificDecorator(Component component) : base(component) { }

    public override void Operation()
    {
        //調用原有的業務方法
        base.Operation();
        //調用新增的業務方法
        this.AddedBehavior();
    }

    //新增業務方法
    private void AddedBehavior()
    {
        //具體裝飾
    }
}

示例場景

開發一個能夠對字符串進行加密的數據加密模塊。提供最簡單的加密算法字母移動實現;提供稍微複雜的逆向輸出加密;提供更爲高級的求模加密。用戶先使用最簡單的加密算法進行加密,若是以爲還不夠能夠對加密後的結果進行二次加密甚至三次加密,使用裝飾模式設計。性能

代碼this

abstract class EncryptionComponent
{
    public abstract void EncryptionOperation(string str);
}

class Encryption : EncryptionComponent
{
    public override void EncryptionOperation(string str)
    {
        Console.WriteLine("對字符串: {0}進行位移加密", str);
    }
}

//抽象裝飾類
class ComponentDecorator : EncryptionComponent
{
    private EncryptionComponent m_Component;

    public ComponentDecorator(EncryptionComponent component)
    {
        this.m_Component = component;
    }

    public override void EncryptionOperation(string str)
    {
        this.m_Component.EncryptionOperation(str);
    }
}

//逆序加密裝飾類(具體裝飾類)
class ReverseDecorator : ComponentDecorator
{
    public ReverseDecorator(EncryptionComponent component) : base(component) { }

    public override void EncryptionOperation(string str)
    {
        base.EncryptionOperation(str);
        this.ReverseEncryption(str);
    }

    private void ReverseEncryption(string str)
    {
        Console.WriteLine("對字符串: {0}進行逆序加密", str);
    }
}

//求模加密裝飾類(具體裝飾類)
class ModDecorator : ComponentDecorator
{
    public ModDecorator(EncryptionComponent component) : base(component) { }

    public override void EncryptionOperation(string str)
    {
        base.EncryptionOperation(str);
        this.ModEncryption(str);
    }

    private void ModEncryption(string str)
    {
        Console.WriteLine("對字符串: {0}進行求模加密", str);
    }
}

不進行加密

static void Main()
{
    EncryptionComponent component = new Encryption();
    //不進行裝飾
    component.EncryptionOperation("裝飾模式");
    Console.ReadKey();
}

運行結果
image.png加密

同時使用逆序加密

static void Main()
{
    EncryptionComponent component = new Encryption();
    EncryptionComponent decorate = new ReverseDecorator(component);
    decorate.EncryptionOperation("裝飾模式");
    Console.ReadKey();
}

運行結果
image.pngspa

同時使用三種加密

static void Main()
{
    EncryptionComponent component = new Encryption();
    EncryptionComponent decorate = new ReverseDecorator(component);
    decorate = new ModDecorator(decorate);
    decorate.EncryptionOperation("裝飾模式");
    Console.ReadKey();
}

運行結果
image.png設計

裝飾模式的優勢

  • 相對繼承而言,擴展更加靈活。
  • 能夠動態擴展對象的職責。
  • 能夠對一個對象進行屢次裝飾,經過不一樣的具體裝飾類以及裝飾類的各自排列組合可以創造出多種不一樣的行爲組合。
  • 具體構件類和具體裝飾類能夠獨立變化,互不影響。

裝飾模式的缺點

  • 裝飾模式設計會致使系統中出現不少小對象,佔用更多的系統資源,影響程序性能。
  • 相對繼承更加靈活卻也更加複雜容易出錯,對於屢次裝修的對象,調試時可能須要逐級定位錯誤,較爲繁瑣。

應用場景

  • 在不影響其它對象的狀況下須要動態的給單個對象添加職責。
  • 不能採用繼承的方式對系統進行擴展或者採用繼承不利於系統的擴展和維護時能夠使用裝飾模式。
相關文章
相關標籤/搜索