装饰器模式(讲解+应用)
轉(zhuǎn)載自?設(shè)計(jì)模式(5)裝飾器模式(講解+應(yīng)用)
目錄
裝飾器模式
為什么使用裝飾器模式
應(yīng)用實(shí)例
裝飾器模式
看到裝飾器是在看《Thinking in Java》一書的時(shí)候,看到文件讀寫那邊的時(shí)候,有提到裝飾器模式,同時(shí)在文件讀寫的那一部分,對(duì)于各種讀入,寫出的方式,代碼組織結(jié)構(gòu)感覺也是比較怪的,怪的總是吸引人的。
裝飾器模式:在不必改變?cè)愇募褪褂美^承的情況下,動(dòng)態(tài)地?cái)U(kuò)展一個(gè)對(duì)象的功能。它是通過(guò)創(chuàng)建一個(gè)包裝對(duì)象,也就是裝飾來(lái)包裹真實(shí)的對(duì)象。
通過(guò)使用裝飾器模式,我們可以實(shí)現(xiàn)關(guān)閉原有代碼,開放現(xiàn)有代碼的方式來(lái)實(shí)現(xiàn)更多的功能。通過(guò)減少對(duì)原有代碼的改變,來(lái)降低犯錯(cuò)誤的幾率。不改變妹子的三圍,通過(guò)裝飾不同的制服,實(shí)現(xiàn)一個(gè)動(dòng)態(tài)擴(kuò)展,我們就會(huì)看到教師,護(hù)士,,,其本質(zhì)功能還是未改變的,只是體驗(yàn)更上一層樓。。。
為什么使用裝飾器模式
繼續(xù)上面的需求來(lái)舉例子吧,現(xiàn)在我們要針對(duì)該服務(wù)場(chǎng)所制定一個(gè)訂單系統(tǒng),當(dāng)客戶來(lái)選擇的時(shí)候,點(diǎn)一項(xiàng)服務(wù),我們需要向訂單中加入一項(xiàng),然后最后計(jì)算一個(gè)總和,由于young woman,student,nurse等基礎(chǔ)價(jià)格是不同的,假設(shè)在其基礎(chǔ)之上的單項(xiàng)服務(wù)價(jià)格是相同的,首先我們想到的可能是根據(jù)不同的類型繼承自一個(gè)基類,建立一個(gè)類,然后每個(gè)作為一個(gè)實(shí)例,將各項(xiàng)服務(wù)作為一個(gè)全局變量,然后各項(xiàng)服務(wù)有一個(gè)set方法,用來(lái)改變這些服務(wù)的狀態(tài),兩次調(diào)用可以取消該服務(wù),默認(rèn)各項(xiàng)服務(wù)的狀態(tài)是關(guān)閉的,然后最后通過(guò)一個(gè)cost方法判斷各種服務(wù)的來(lái)計(jì)算總價(jià)格,當(dāng)然感覺這是一個(gè)很不錯(cuò)的方法。但是由于某種服務(wù)的特殊性原因,能提供該服務(wù)的人減少,所以該服務(wù)價(jià)格上漲,或者是在某種服務(wù)在一個(gè)不小心中誕生,因此,我們需要打開源代碼進(jìn)行添加一些服務(wù),然后需要添加set方法,同時(shí),我們需要對(duì)cost進(jìn)行修改,隨著人民思路不斷開闊,冒險(xiǎn)精神日益增強(qiáng),各種服務(wù)如雨后春筍,我們的維護(hù)工作將變得比工作人員還要辛苦了。這個(gè)時(shí)候,就要引出我們的裝飾器模式,我們將所有需要付費(fèi)的拿出來(lái),因?yàn)槲覀冊(cè)诤笃诘木S護(hù)上,就是價(jià)格導(dǎo)致的變化給我們帶來(lái)了困擾,所以如果將這些變化的價(jià)格拿出來(lái),單獨(dú)維護(hù),我們的工作量將會(huì)減少。如下結(jié)構(gòu)
//基礎(chǔ)抽象類 public abstract class SexService{String description = "Best Service";public String getDescription(){return description;}public abstract int cost(); } //繼承自抽象類的本體 public class Nurse extends SexService{public Nurse(){description = "You konw";}public int cost(){return 150;} } //繼承自基礎(chǔ)類的用來(lái)修飾本體的類 public class PlayXiao extends SexService{SexService service;public PlayXiao(SexService service){this.service = service;}public String getDescription(){return service.getDescription+"PlayXiao";}public int cost(){return service.cost+50;}}調(diào)用方式
Nurse sweetHeart = new Nurse(); sweetHeart = new PlayXiao(sweetHeart);首先我們創(chuàng)建一個(gè)本體類,然后將其作為一個(gè)實(shí)例通過(guò)構(gòu)造函數(shù)注入到一個(gè)裝飾類,在裝飾類內(nèi)部通過(guò)委托的形式獲得當(dāng)前的價(jià)格和描述,同時(shí)由于本體類和裝飾類繼承自同一個(gè)基類,所以可以用來(lái)繼續(xù)向下傳遞。
基礎(chǔ)抽象類,通過(guò)構(gòu)造函數(shù)進(jìn)行實(shí)例注入,通過(guò)委托實(shí)現(xiàn)狀態(tài),數(shù)據(jù)更新,從而實(shí)現(xiàn)關(guān)閉原有代碼,開放現(xiàn)有代碼。
應(yīng)用實(shí)例
言歸正傳,回到正題上來(lái),講一下其在我們平常開發(fā)中的例子
開始也提到了一點(diǎn)關(guān)于Java,io庫(kù)的問(wèn)題
java I/O庫(kù)具有兩個(gè)對(duì)稱性,它們分別是:
輸入-輸出對(duì)稱:比如InputStream 和OutputStream 各自占據(jù)Byte流的輸入和輸出的兩個(gè)平行的等級(jí)結(jié)構(gòu)的根部;而Reader和Writer各自占據(jù)Char流的輸入和輸出的兩個(gè)平行的等級(jí)結(jié)構(gòu)的根部。
byte-char對(duì)稱:InputStream和Reader的子類分別負(fù)責(zé)byte和Char流的輸入;OutputStream和Writer的子類分別負(fù)責(zé)byte和Char流的輸出
這些作為根類,如果我們想通過(guò)緩沖,字節(jié),或者是管道,這個(gè)時(shí)候我們就需要使用裝飾器來(lái)進(jìn)行裝飾,然后通過(guò)裝飾器來(lái)實(shí)現(xiàn)相應(yīng)的操作,根類具有read方法,對(duì)于裝飾類,通過(guò)構(gòu)造函數(shù)將基類的一個(gè)實(shí)例注入進(jìn)去,然后通過(guò)委托模式,首先通過(guò)基類的read方法獲取字節(jié)流,然后根據(jù)相應(yīng)的操作,實(shí)現(xiàn)字節(jié)讀取等。
InputStreamReader input = new InputStreamReader(System.in); BufferedReader reader = new BufferedReader(input); String line = reader.readLine();總結(jié)
以上是生活随笔為你收集整理的装饰器模式(讲解+应用)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 梦幻西游对电脑的要求是不是很低?
- 下一篇: 组合模式的安全模式与透明模式