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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

《设计模式》之装饰器模式

發(fā)布時間:2023/12/29 asp.net 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《设计模式》之装饰器模式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、什么是裝飾器模式

當(dāng)需要對類的功能進行拓展時,一般可以使用繼承,但如果需要拓展的功能種類很繁多,那勢必會生成很多子類,增加系統(tǒng)的復(fù)雜性,并且使用繼承實現(xiàn)功能拓展時,我們必須能夠預(yù)見這些拓展功能,也就是這些功能在編譯時就需要確定了。那么有什么更好的方式實現(xiàn)功能的拓展嗎?答案就是裝飾器模式。

裝飾器模式可以動態(tài)給對象添加一些額外的職責(zé)從而實現(xiàn)功能的拓展,在運行時選擇不同的裝飾器,從而實現(xiàn)不同的行為;比使用繼承更加靈活,通過對不同的裝飾類進行排列組合,創(chuàng)造出很多不同行為,得到功能更為強大的對象;符合“開閉原則”,被裝飾類與裝飾類獨立變化,用戶可以根據(jù)需要增加新的裝飾類和被裝飾類,在使用時再對其進行組合,原有代碼無須改變。

但是裝飾器模式也存在缺點,首先會產(chǎn)生很多的小對象,增加了系統(tǒng)的復(fù)雜性,第二是排錯比較困難,對于多次裝飾的對象,調(diào)試時尋找錯誤可能需要逐級排查,較為煩瑣。

二、UML結(jié)構(gòu)圖

  • Component:抽象構(gòu)件,是定義一個對象接口,可以給這個對象動態(tài)地添加職責(zé)。
  • ConcreteComponent:具體構(gòu)件,是定義了一個具體的對象,也可以給這個對象添加一些職責(zé)。
  • Decorator:抽象裝飾類,繼承自 Component,從外類來擴展 Component 類的功能,但對于 Component 來說,是無需知道 Decorator 存在的。
  • ConcreteDecorator:具體裝飾類,起到給 Component 添加職責(zé)的功能。

裝飾者與被裝飾者都擁有共同的超類,但這里繼承的目的是繼承類型,而不是行為。

三、代碼實現(xiàn)

3.1、代碼示例一

//定義被裝飾者 interface Human {void wearClothes(); }//定時裝飾者 abstract class Decorator implements Human {private Human human;public Decorator(Human human){this.human = human;}@Overridepublic void wearClothes(){human.wearClothes();} }//下面定義三種裝飾,這是第一個,第二個第三個功能依次細(xì)化,即裝飾者的功能越來越多 class Decorator_zero extends Decorator {public Decorator_zero(Human human) {super(human);}public void goHome() {System.out.println("進房子。。");}@Overridepublic void wearClothes() {super.wearClothes();goHome();} }class Decorator_first extends Decorator {public Decorator_first(Human human) {super(human);}public void goClothespress() {System.out.println("去衣柜找找看。。");}@Overridepublic void wearClothes() {super.wearClothes();goClothespress();} }class Decorator_two extends Decorator {public Decorator_two(Human human) {super(human);}public void findClothes() {System.out.println("找到一件D&G。。");}@Overridepublic void wearClothes() {super.wearClothes();findClothes();} }class Person implements Human {@Overridepublic void wearClothes() {System.out.println("穿什么呢。。");} }//測試類 public class DecoratorTest {public static void main(String[] args){Human person = new Person();Decorator decorator = new Decorator_two(new Decorator_first(new Decorator_zero(person)));decorator.wearClothes();} }

運行結(jié)果:

其實就是進房子找衣服,通過裝飾者的三層裝飾,把細(xì)節(jié)變得豐富,該Demo的關(guān)鍵點:

(1)Decorator 抽象類持有Human接口,方法全部委托給該接口調(diào)用,目的是交給該接口的實現(xiàn)類進行調(diào)用。

(2)Decorator 抽象類的子類,即具體裝飾者,里面都有一個構(gòu)造方法調(diào)用 super(human),這里就體現(xiàn)了抽象類依賴于子類實現(xiàn),即抽象依賴于實現(xiàn)的原則。因為構(gòu)造函數(shù)的參數(shù)都是 Human 類型,只要是該 Human 的實現(xiàn)類都可以傳遞進去,即表現(xiàn)出 Decorator dt = new Decorator_second(new Decorator_first(new Decorator_zero(human))) 這種結(jié)構(gòu)的樣子,所以當(dāng)調(diào)用 dt.wearClothes() 的時候,又因為每個具體裝飾者類中,都先調(diào)用 super.wearClothes() 方法,而該 super 已經(jīng)由構(gòu)造函數(shù)傳遞并指向了具體的某一個裝飾者類,那么最終調(diào)用的就是裝飾類的方法,然后才調(diào)用自身的裝飾方法,即表現(xiàn)出一種裝飾、鏈?zhǔn)降念愃朴谶^濾的行為。

(3)具體被裝飾者類,可以定義初始的狀態(tài)或者初始的自己的裝飾,后面的裝飾行為都在此基礎(chǔ)上一步一步進行點綴、裝飾。

(4)裝飾者模式的設(shè)計原則為:對擴展開放、對修改關(guān)閉,這句話體現(xiàn)在如果想擴展被裝飾者類的行為,無須修改裝飾者抽象類,只需繼承裝飾者抽象類,實現(xiàn)額外的一些裝飾或者叫行為即可對被裝飾者進行包裝。所以:擴展體現(xiàn)在繼承、修改體現(xiàn)在子類中,而不是具體的抽象類,這充分體現(xiàn)了依賴倒置原則,這是自己理解的裝飾者模式。

3.2、代碼示例二

現(xiàn)在需要一個漢堡,主體是雞腿堡,可以選擇添加生菜、醬、辣椒等等許多其他的配料,這種情況下就可以使用裝飾者模式。

漢堡基類(被裝飾者,相當(dāng)于上面的Human)

public abstract class Humburger { protected String name ; public String getName(){ return name; } public abstract double getPrice(); }

雞腿堡類(被裝飾者的初始狀態(tài),有些自己的簡單裝飾,相當(dāng)于上面的Person)?

public class ChickenBurger extends Humburger { public ChickenBurger(){ name = "雞腿堡"; } @Override public double getPrice() { return 10; } }

配料的基類(裝飾者,用來對漢堡進行多層裝飾,每層裝飾增加一些配料,相當(dāng)于上面Decorator)

public abstract class Condiment extends Humburger { public abstract String getName(); }

生菜(裝飾者的第一層,相當(dāng)于上面的decorator_zero)

public class Lettuce extends Condiment { Humburger humburger; public Lettuce(Humburger humburger){ this.humburger = humburger; } @Override public String getName() { return humburger.getName()+" 加生菜"; } @Override public double getPrice() { return humburger.getPrice()+1.5; } }

辣椒(裝飾者的第二層,相當(dāng)于上面的decorator_first)

public class Chilli extends Condiment { Humburger humburger; public Chilli(Humburger humburger){ this.humburger = humburger; } @Override public String getName() { return humburger.getName()+" 加辣椒"; } @Override public double getPrice() { return humburger.getPrice(); //辣椒是免費的哦 } }

測試類:

package decorator; public class Test { public static void main(String[] args) { Humburger humburger = new ChickenBurger(); System.out.println(humburger.getName()+" 價錢:"+humburger.getPrice()); Lettuce lettuce = new Lettuce(humburger); System.out.println(lettuce.getName()+" 價錢:"+lettuce.getPrice()); Chilli chilli = new Chilli(humburger); System.out.println(chilli.getName()+" 價錢:"+chilli.getPrice()); Chilli chilli2 = new Chilli(lettuce); System.out.println(chilli2.getName()+" 價錢:"+chilli2.getPrice()); } }

輸出:

雞腿堡 ?價錢:10.0 ?
雞腿堡 加生菜 ?價錢:11.5 ?
雞腿堡 加辣椒 ?價錢:10.0 ?
雞腿堡 加生菜 加辣椒 ?價錢:11.5 ?

原文鏈接:?Java設(shè)計模式之結(jié)構(gòu)型:裝飾器模式_張維鵬的博客-CSDN博客?

總結(jié)

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

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