日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

【设计模式 03】装饰模式——俄罗斯套娃?

發布時間:2023/12/20 asp.net 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【设计模式 03】装饰模式——俄罗斯套娃? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

裝飾模式(俄羅斯套娃?)

裝飾模式:動態的給某些對象添加額外的功能

參考:

  • 簡書 | 裝飾模式

  • 博客園 | 簡說設計模式——裝飾模式

  • 博客園 | 裝飾器模式 Decorator 結構型 設計模式 (十)

什么是裝飾模式

裝飾模式也叫裝飾器模式,python中的裝飾器就是這種模式的體現,對于一個類,如果要添加一個新功能,除了修改代碼外(違反開閉原則),可以使用繼承,但通過繼承添加新功能并不適合所有場景,如

  • 類不可見或不允許繼承
  • 需要對一批類似的兄弟類添加同一個新功能時,繼承會產生大量的子類
  • 希望新功能的添加和撤銷是動態的
  • 裝飾模式中的對象包括:

  • 裝飾器(用來為被裝飾對象動態添加新功能)

  • 抽象被裝飾對象(所有能被裝飾對象的抽象)

  • 被裝飾對象

  • 客戶端如果希望給某個對象動態添加一個新功能,就可以把這個對象(被裝飾對象)傳遞給裝飾器,由裝飾器實現新功能,并保存一個被裝飾對象的引用,并返回給客戶端一個裝飾器對象,這樣,被裝飾對象原來的行為和屬性并沒有改變,甚至被裝飾對象本身就沒有改變,只是在外面套了一個殼子,新功能是這個殼子提供的。就像TCP/IP協議棧中,應用層的數據包到傳輸層通過加TCP或UDP首部來傳輸一樣。

    裝飾模式優缺點

    優點:

  • 一個裝飾器可以給多個不同的類動態添加新功能
  • 新功能由裝飾器實現,不需要修改被裝飾對象,有一定的安全性
  • 多個裝飾器可以配合嵌套使用,以此實現更復雜的功能
  • 新功能不影響原來的功能,添加和撤銷都方便
  • 缺點:

  • 過多的裝飾類可能使程序變得很復雜

  • 裝飾模式是針對抽象組件(Component)類型編程。但是,如果你要針對具體組件編程時,就應該重新思考你的應用架構,以及裝飾者是否合適。當然也可以改變Component接口,增加新的公開的行為,實現“半透明”的裝飾者模式。在實際項目中要做出最佳選擇。

    作者:慵懶的陽光丶

  • 適用場景

  • 要添加的新功能與原有類關聯不大時
  • 新功能需要方便添加和撤銷時
  • 不能或不方便通過繼承實現新功能時
  • 比如賣烤冷面,最基本的就是面(抽象被裝飾對象)具體的就是烤冷面(被裝飾對象),然后可以往面里面加各種配料(抽象裝飾器),如雞蛋,辣條等(具體裝飾器),由于不同配料的加入順序對最后的烤冷面有影響,所以如果要用繼承拓展“烤冷面”,那先加雞蛋再加辣條和先加辣條再加雞蛋就需要寫兩個子類,造成冗余重復,這種場景就適合適用裝飾模式。

    抽象被裝飾對象

    package pers.junebao.decorator_pattern;public abstract class Noodles {public String rawMaterial; // 配料public abstract void sayWhoAmI(); }

    具體的被裝飾對象:

    package pers.junebao.decorator_pattern;public class BakedColdNoodles extends Noodles {BakedColdNoodles() {this.rawMaterial = "面"; // 最原始的烤冷面,配料只有面}@Overridepublic void sayWhoAmI() {System.out.println("我是普通烤冷面!");} }

    抽象裝飾器:

    package pers.junebao.decorator_pattern.decorator;import pers.junebao.decorator_pattern.Noodles;public abstract class Burden extends Noodles {public Noodles noodles; // 裝飾器中保留一份被裝飾對象的引用,方便客戶端使用public Burden(Noodles noodles) {this.noodles = noodles;} }
    • 裝飾器是為某一類對象提供裝飾的(這里就是實現了Noodles 的類)

    具體的裝飾器類:

    • 加雞蛋

      package pers.junebao.decorator_pattern.decorator;import pers.junebao.decorator_pattern.Noodles;public class AddEggs extends Burden {public AddEggs(Noodles noodles) {super(noodles);this.rawMaterial = noodles.rawMaterial + ", 雞蛋";}@Overridepublic void sayWhoAmI() {System.out.println("我是加了雞蛋的烤冷面!!");}}
    • 加辣條

      package pers.junebao.decorator_pattern.decorator;import pers.junebao.decorator_pattern.Noodles;public class AddSpicyStrips extends Burden{public AddSpicyStrips(Noodles noodles) {super(noodles);this.rawMaterial = noodles.rawMaterial + " ,辣條";}@Overridepublic void sayWhoAmI() {System.out.println("我是加了辣條的烤冷面!!");} }

    客戶端:

    package pers.junebao.decorator_pattern;import pers.junebao.decorator_pattern.decorator.AddEggs; import pers.junebao.decorator_pattern.decorator.AddSpicyStrips;public class Main {public static void main(String[] args) {Noodles bcn = new BakedColdNoodles();Noodles bcnAddEgg = new AddEggs(bcn);bcnAddEgg.sayWhoAmI();System.out.println(bcnAddEgg.rawMaterial);Noodles bcnEggSpicyS = new AddSpicyStrips(bcnAddEgg);bcnEggSpicyS.sayWhoAmI();System.out.println(bcnEggSpicyS.rawMaterial);} } /* 我是加了雞蛋的烤冷面!! 面, 雞蛋 我是加了辣條的烤冷面!! 面, 雞蛋 ,辣條*/

    這樣如果想先加辣條在家雞蛋,就可以使用AddSpicyStrips先裝飾BakedColdNoodles,再用AddEggs裝飾AddSpicyStrips。

    GitHub | 完整代碼

    總結

    以上是生活随笔為你收集整理的【设计模式 03】装饰模式——俄罗斯套娃?的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。