日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

设计模式 | 装饰模式

發(fā)布時(shí)間:2023/12/29 52 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式 | 装饰模式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1 | 裝飾模式的概述

我們?cè)诹私庋b飾模式之前,先回顧下生活中的幾個(gè)常見(jiàn)現(xiàn)象,舉例如下:

  • 新房的裝修,房屋裝修并沒(méi)有改變房屋居住的本質(zhì),但可以讓房屋變得更漂亮,更溫馨,更實(shí)用,更滿足居家需求。
  • 相片的包裝,照相館中把原相片清洗出來(lái)后,會(huì)對(duì)上面做些包裝/裝飾,相片鍍膜,添加相框等處理,讓整體更加美觀,防潮保存更長(zhǎng)的時(shí)間。

在軟件設(shè)計(jì)中,類似上面的場(chǎng)景我們也可以把對(duì)象在不改變結(jié)構(gòu)的情況下對(duì)其加工擴(kuò)展修飾,使得對(duì)象具有更加強(qiáng)大的功能,這種技術(shù)在設(shè)計(jì)模式中就叫裝飾模式。裝飾模式可以在不改變一個(gè)對(duì)象本身功能的基礎(chǔ)上給對(duì)象增加額外的新行為。

1.1 裝飾模式的定義

  • 裝飾模式:動(dòng)態(tài)地給一個(gè)對(duì)象增加一些額外的職責(zé)。就擴(kuò)展功能面言,裝飾模式提供了—種比使用子類更加靈活的替代方案。
  • Decorator Pattern:Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to subclassing for extending functionality.

裝飾模式是一種對(duì)象結(jié)構(gòu)型模式,它以對(duì)客戶透明的方式動(dòng)態(tài)地給一個(gè)對(duì)象附加上更多的責(zé)任,可以在不需要?jiǎng)?chuàng)建更多子類的情況下,讓對(duì)象的功能得以擴(kuò)展。

裝飾模式是一種用于替代繼承的技術(shù),它通過(guò)一開(kāi)無(wú)須定義子類的方式給對(duì)象動(dòng)態(tài)增加職責(zé),使用對(duì)象之間的關(guān)聯(lián)天系取代類之間的繼承關(guān)系。裝飾模式降低了系統(tǒng)的耦合度。可以動(dòng)態(tài)增加或刪除對(duì)象的職責(zé),并使得需要裝飾的具體構(gòu)件類和用于裝飾的具體裝飾類都可以獨(dú)立變化,增加新的具體構(gòu)件類和具體裝飾類都非常方便,符合開(kāi)閉原則。

2 |?裝飾模式的結(jié)構(gòu)與實(shí)現(xiàn)

2.1?裝飾模式的結(jié)構(gòu)

類圖結(jié)構(gòu)

裝飾模式包含以下 4 個(gè)角色

  • (1) Componcnt(抽象構(gòu)件),它是具體構(gòu)件和抽象裝飾類的共同父奧,聲明了在具體構(gòu)件中實(shí)轟的業(yè)備方法,它的引入可以使客戶湖以一致的方式處理未被裝飾的對(duì)象以及裝飾之后的對(duì)象,字現(xiàn)客戶端的透明操作。
  • (2) ConcreteComponent(具體鉤件),它是抽象構(gòu)件類的子類,用于定義具體的構(gòu)件對(duì)象,實(shí)現(xiàn)了在抽象物件中聲明的方法,裝飾類可以給它增加額外的職責(zé)(方法)。
  • (3) Decorater(抽象裝飾類),它也是抽象構(gòu)件類的子類,用于給具體構(gòu)件增加職責(zé),但是具體職責(zé)通常在其子類中實(shí)艦,它維護(hù)一個(gè)指向抽象構(gòu)件對(duì)象的引用,通過(guò)該引用可以調(diào)用裝飾之前構(gòu)件對(duì)象的方法,并通過(guò)其子面擴(kuò)展該方法,以達(dá)到裝飾的目的。
  • (4) ConcreteDecorator(具體裝飾類),它是抽象裝飾類的子類,負(fù)責(zé)向構(gòu)件添加新的職責(zé),每一個(gè)具體裝飾類都定義了一些新的行為,它可以調(diào)用在抽象裝飾類中定義的方法,并且可以增加新的方法,以實(shí)現(xiàn)擴(kuò)展對(duì)象的行為。

2.2?裝飾模式的實(shí)現(xiàn)

【抽象構(gòu)件類/Component】一般設(shè)計(jì)為抽象類或者接口,在其中聲明了抽象業(yè)務(wù)方法,當(dāng)然,也可以在抽象構(gòu)件類中實(shí)現(xiàn)一些所有具體構(gòu)件類都共有的業(yè)務(wù)方法。抽象構(gòu)件類的典型代碼如下:

abstract class Component {public abstract void Operation(); }

【具體構(gòu)件類/ConcreteComponent?】作為抽象構(gòu)件類的子類實(shí)現(xiàn)了在抽象構(gòu)件類中聲明的業(yè)務(wù)方法,通常在具體構(gòu)件類中只提供基本功能的實(shí)現(xiàn),一些復(fù)雜的功能需通過(guò)裝飾類來(lái)進(jìn)行擴(kuò)展,其典型代碼如下:

class ConcreteComponent : Component {public override void Operation(){Console.WriteLine("基本功能實(shí)現(xiàn)");} }

【抽象裝飾類/Decorator?】裝飾模式的核心在于裝飾類的設(shè)計(jì),其典型代碼如下:

class Decorator : Component {private readonly Component _Component; //維持一個(gè)對(duì)抽象構(gòu)件對(duì)象的引用//注入一個(gè)抽象構(gòu)件類型的對(duì)象public Decorator(Component component){_Component = component;}public override void Operation(){_Component.Operation(); //調(diào)用原有業(yè)務(wù)方法} }

【具體裝飾類/ConcreteDecorator】是抽象裝飾類的子類,可以根據(jù)需要對(duì)父類方法?Operation()?進(jìn)行擴(kuò)展,典型代碼如下:

class ConcreteDecorator : Decorator {public ConcreteDecorator(Component component) : base(component){}public override void Operation() {base.Operation(); //調(diào)用原有業(yè)務(wù)方法AddedBehavior(); //調(diào)用新增業(yè)務(wù)方法}//新增業(yè)務(wù)方法public void AddedBehavior() { Console.WriteLine("功能擴(kuò)展實(shí)現(xiàn)");} }

在具體裝飾類中可以調(diào)用抽象裝飾類的?Operation()?方法,同時(shí)可以定義新的業(yè)務(wù)方法,例如?AddedBehavior() ,如果該方法不希望客戶端單獨(dú)調(diào)用,還可以將其可訪問(wèn)性修改為私有(private)。

客戶端調(diào)用

3 |?裝飾模式的應(yīng)用實(shí)例

3.1?實(shí)例說(shuō)明

某軟件公司基于面向?qū)ο蠹夹g(shù)開(kāi)發(fā)了一套圖形界面構(gòu)件庫(kù)——VisualComponent。該構(gòu)件庫(kù)提供了大量的基本構(gòu)件,如窗體、文本框、列表框等,由于在使用該構(gòu)件庫(kù)時(shí),用戶經(jīng)常要求定制一些特殊的顯示效果,如帶滾動(dòng)條的窗體、帶黑色邊框的文本框,既帶滾動(dòng)條又帶黑色邊框的列表框等,因此經(jīng)常需要對(duì)該構(gòu)件庫(kù)進(jìn)行擴(kuò)展以增強(qiáng)其功能,現(xiàn)使用裝飾模式來(lái)設(shè)計(jì)該圖形界面構(gòu)件庫(kù)。

3.2?實(shí)例代碼設(shè)計(jì)

類圖結(jié)構(gòu)

示例代碼說(shuō)明

  • VisualComponent :抽象界面構(gòu)件類,充當(dāng)抽象構(gòu)建類。
  • Window、TextBox、ListBox :VisualComponent?的派生類,充當(dāng)具體構(gòu)建類。
  • ComponentDecorator :VisualComponent?的派生類,充當(dāng)抽象裝飾器類。
  • BlackBorderDecorator、ScrollBarDecorator :ComponentDecorator?的派生類,充當(dāng)具體裝飾類。

客戶端調(diào)用

如果需要在原系統(tǒng)中增加一個(gè)新的具體構(gòu)建類或者新的具體裝飾類,無(wú)須修改現(xiàn)有的類庫(kù)代碼,只需將他們分別作為抽象構(gòu)建類或者抽象裝飾類的子類即可。

完整代碼示例請(qǐng)查看 =》https://gitee.com/dolayout/DesignPatternOfCSharp/tree/master/DesignPatternOfCSharp/DecoratorPattern

4 |?透明裝飾模式與半透明裝飾模式

在裝飾模式中,具體裝飾類通過(guò)新增成員變量或者成員方法來(lái)擴(kuò)展具體構(gòu)建類的功能。

  • 在標(biāo)準(zhǔn)的裝飾模式中,新增行為需要在原有的業(yè)務(wù)方法中調(diào)用,無(wú)論是具體構(gòu)建對(duì)象還是裝飾過(guò)后的構(gòu)建對(duì)象,對(duì)于客戶端而言都是透明的,這種裝飾模式被稱為透明(Transparent)裝飾模式
  • 但是在某些情況下,有些新增行為可能需要單獨(dú)被調(diào)用,此時(shí),客戶端不能再一致性地處理裝飾之前的對(duì)象和裝飾之后的對(duì)象,這種裝飾模式被稱為半透明(Semi-transparent)裝飾模式

下面將對(duì)這兩種裝飾模式進(jìn)行較為詳細(xì)的介紹。

4.1 透明裝飾模式

在透明裝飾模式中,要求客戶端完全針對(duì)抽象編程,裝飾模式的透明性要求客戶端程序不應(yīng)該將對(duì)象聲明為具體構(gòu)件類型或具體裝飾類型,而應(yīng)該全部聲明為抽象構(gòu)件類型。對(duì)于客戶端而言,具體構(gòu)件對(duì)象和具體裝飾對(duì)象沒(méi)有任何區(qū)別。即應(yīng)該使用以下代碼:

Component component = new ConcreteComponent(); //推薦:使用抽象構(gòu)件類型定義對(duì)象 //ConcreteComponent component = new ConcreteComponent(); //不推薦:使用具體構(gòu)件類型定義對(duì)象Decorator decorator = new ConcreteDecorator(component); //推薦:抽象裝飾器類型定義對(duì)象 //ConcreteDecorator decorator = new ConcreteDecorator(component); //不推薦:具體裝飾器類型定義對(duì)象

對(duì)于多次裝飾而言,在客戶端中存在以下代碼片段:

Component component_o, component_d1, component_d2; //全部使用抽象構(gòu)件定義 component_o = new ConcreteComponent(); component_d1 = new ConcreteDecoratoz1(component_o); component_d2 = new ConcreteDecorator2(component_d1); component_d2.Operation(); //無(wú)法單獨(dú)調(diào)用 component_d2 的 AddedBehavior() 方法

使用抽象構(gòu)件類型 Component 定義全部具體構(gòu)件對(duì)象和具體裝飾對(duì)象,客戶端可以一致地使用這此對(duì)象,因此符合透明裝飾模式的要求。
透明裝飾模式可以讓客戶端透明地使用裝飾之前的對(duì)象和裝飾之后的對(duì)象,無(wú)須關(guān)心它們的區(qū)別,此外,還可以對(duì)一個(gè)已裝飾過(guò)的對(duì)象進(jìn)行多次裝飾,得到更為復(fù)雜、功能更為強(qiáng)大的對(duì)象,在實(shí)現(xiàn)透明裝飾模式時(shí),要求具體裝飾類的 Operation() 方法覆蓋抽象裝飾類的 Operation() 方法,除了調(diào)用原有對(duì)象的 Operation() 外還需要調(diào)用新增的 AddedBehavior() 方法來(lái)增加新行為。但是由于在抽象構(gòu)件中并沒(méi)有聲明 AddedBehavior() 方法,因此,無(wú)法在客戶端單獨(dú)調(diào)用該方法,上面的圖形界面構(gòu)件庫(kù)的設(shè)計(jì)方案中使用的就是透明裝飾模式。

4.2?半透明裝飾模式

透明裝飾模式的設(shè)計(jì)難度較大,而且有時(shí)需要單獨(dú)調(diào)用新增的業(yè)務(wù)方法,為了能夠調(diào)用到新增的方法,不得不用具體的裝飾類來(lái)定義裝飾后的對(duì)象,而具體構(gòu)件可以繼續(xù)使用抽象對(duì)象構(gòu)件類型來(lái)定義,這種裝飾模式即為半透明裝飾模式。

客戶端調(diào)用

  • 具體構(gòu)件類型無(wú)須關(guān)心,是透明的,使用抽象構(gòu)建類型定義;
  • 具體裝飾類型必須指定,是不透明的,使用具體裝飾類型定義;
  • 客戶端示例代碼片段如下:

    Component component = new ConcreteComponent(); //使用抽象構(gòu)建類型定義 ConcreteDecorator decorator = new ConcreteDecorator(component); //使用具體裝飾類型定義 decorator.Operation(); //調(diào)用單獨(dú)的新增業(yè)務(wù)方法

    半透明裝飾模式可以給系統(tǒng)帶來(lái)更多的靈活性,設(shè)計(jì)相對(duì)簡(jiǎn)單,使用起來(lái)也非常方便;但是其最大的缺點(diǎn)在于不能實(shí)現(xiàn)對(duì)同一個(gè)對(duì)象的多次裝飾,而且客戶端需要有區(qū)別地對(duì)待裝飾之前的對(duì)象和裝飾之后的對(duì)象。在實(shí)現(xiàn)半透明的裝飾模式時(shí),只需在具體裝飾類中增加一個(gè)獨(dú)立的 AddedBehavior() 方法來(lái)封裝相應(yīng)的業(yè)務(wù)處理即可,由于客戶端使用具體裝飾類型來(lái)定義裝飾后的對(duì)象,因此可以單獨(dú)調(diào)用 AddedBehavior() 方法。

    5 | 裝飾模式的優(yōu)缺點(diǎn)與適用環(huán)境

    裝飾模式降低了系統(tǒng)的耦合度,可以動(dòng)態(tài)增加或刪除對(duì)象的職責(zé),并使得需要裝飾的具體構(gòu)件類和用于裝飾的具體裝飾類可以獨(dú)立變化,以便增加新的且休構(gòu)件米和且體裝飾類。使用裝飾模式將大大減少子類的個(gè)數(shù),讓系統(tǒng)擴(kuò)展起來(lái)更加方俑,而日更災(zāi)具維護(hù),是取代繼承復(fù)用的有效方式之一。在軟件開(kāi)發(fā)中,裝飾模式得到了較為廣泛的應(yīng)用。

    5.1 裝飾模式的優(yōu)點(diǎn)

    • (1)對(duì)于擴(kuò)展一個(gè)對(duì)象的功能,裝飾模式比繼承更加靈活,不會(huì)導(dǎo)致類的個(gè)數(shù)急劇增加。
    • (2)裝飾模式可以通過(guò)一種動(dòng)態(tài)的方式來(lái)擴(kuò)展一個(gè)對(duì)象的功能,通過(guò)配置文件可以在運(yùn)行時(shí)選擇不同的具體裝飾類,從而實(shí)現(xiàn)不同的行為。
    • (3)裝飾模式可以對(duì)一個(gè)對(duì)象進(jìn)行多次裝飾,通過(guò)使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創(chuàng)造出很多不同行為的組合,得到功能更為強(qiáng)大的對(duì)象。
    • (4)在裝飾模式中,具體構(gòu)件類與具體裝飾類是可以獨(dú)立變化的,用戶可以根據(jù)需要增加新的具體構(gòu)件類和具體裝飾類,且原有類庫(kù)代碼無(wú)須改變,符合開(kāi)閉原則。

    5.2 裝飾模式的缺點(diǎn)

    • (1)使用裝飾模式進(jìn)行系統(tǒng)設(shè)計(jì)時(shí)將產(chǎn)生很多小對(duì)象,這些對(duì)象的區(qū)別在于它們之間相互連接的方式有所不同,而不是它們的類或者屬性值有所不同,大量小對(duì)象的產(chǎn)生勢(shì)必會(huì)占用更多的系統(tǒng)資源,在一定程度上影響程序的性能。
    • (2)裝飾模式提供了一種比繼承更加靈活機(jī)動(dòng)的解決方案,但同時(shí)也意味著比繼承更加易于出錯(cuò),排錯(cuò)也更困難,對(duì)于多次裝飾的對(duì)象,調(diào)試時(shí)尋找錯(cuò)誤可能需要逐級(jí)排查,較為煩瑣。

    5.3 裝飾模式的適用環(huán)境

    • (1)在不影響其他對(duì)象的情況下,以動(dòng)態(tài)、透明的方式給單個(gè)對(duì)象添加職責(zé)。
    • (2)當(dāng)不能采用繼承的方式對(duì)系統(tǒng)進(jìn)行擴(kuò)展或者采用繼承不利于系統(tǒng)擴(kuò)展和維護(hù)時(shí)可以使用裝飾模式。

    不能采用繼承的情況主要有兩種:

  • 第一種是系統(tǒng)中存在大量獨(dú)立的擴(kuò)展,為支持每一種擴(kuò)展或者擴(kuò)展之間的組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長(zhǎng);
  • 第二種是因?yàn)轭愐讯x為不能被繼承(例如 C# 語(yǔ)言中的密封類,即使用 sealed 關(guān)鍵字修飾的類);
  • 總結(jié)

    以上是生活随笔為你收集整理的设计模式 | 装饰模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。