Java設計模式之裝飾模式趣談
本文由碼農網 – 魯阿皓原創,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
前情提要:http://blog.
JVM:”上次給我招的工人不錯啊!”
oo程式設計師:”………..”
JVM:”現在來我開的博物館生意越來越好了,原來”舞臺劇”的方式已經不能滿足顧客的需求了”
oo程式設計師:”………..”
JVM:”我決定要換一種運營模式,把每個演播廳都租出去,讓那些想表演節目的物件們來租演播廳和相關器械,這樣我就能坐地收錢了!”
oo程式設計師:”………..”
JVM:”合夥幹吧?怎麼樣?你三我七!”
oo程式設計師:”………..”
JVM:”四六?”
oo程式設計師:”成交!先說說需求。”
JVM:”首先有不同型別的演播廳和不同的裝飾品/器械,每種物品都要付一定的租金,你要做的就是一件事,把總租金(演播廳+飾品/器械)算出來。”
oo程式設計師:”把價格表給我!”
卡通演播廳(CartoonStudio) 100
小丑演播廳(JokerStudio) 150
超級演播廳(SuperStudio) 300
氣球(Balloon) 10
燈光(Lamplight) 25
麥克風(Microphone) 20
最後還寫下了這個:
public abstract class Anything_ex() { String description=" "; public String getDescription() { return description; } public abstract int cost(); }
仔細一想也對,無論是演播廳還是裝飾品,都需要描述(description)和cost(價格),寫一個共同的父類無可厚非。
接著寫下你設計的第一個類:
class CartoonandBalloon extends Anything_ex { .... public int cost() { return 100+10; } } //帶氣球的卡通演播廳
第二個:
class CartoonandLamplight extends Anything_ex { ... public int cost() { return 100+25; } } //帶燈光的卡通演播廳
第三個:
。。。。。
沒有第三個了!這樣寫下去可是無窮無盡的!沒辦法,換個思路。
在演播廳裡,無論什麼裝飾品都有可能出現,可以把演播廳+飾品看成一個整體,通過飾品相應的has和set來控制飾品,這樣的話,設計出來的類如下:
class CartoonStudio extends Anything_ex { private boolean Balloon=false; .... //省略其他變數,這裡只以氣球為例 public boolean hasBalloon() { return Ballon; } public void setBallon() { Balloon=true; } .......//省略其他has/set方法 public int cost() { int cost=100; //卡通演播廳的初始價格為100 if(hasBalloon) { cost+=10; } else if(hasXXX).....//省略類推下來的程式碼 return cost; } }
這個看起來好多了,不用寫大爆炸數量的類,雖然類寫起來又臭(無數的has/set)又長(的確很長)。。。。。
但是有沒有更好的方案?
答案當然是有的,不過我們必須先明確一下,上述設計的缺點。
- 1.臭
- 2.長
- 3.當飾品的租金改變的時候,必須修改所有演播廳的程式碼(cost部分),我們當然不想這樣,我們想盡可能的少修改程式碼(鬆耦合)。
- 4.沒有面對超類/介面程式設計。
- 5.沒有將變化的部分獨立開。
- 6.組合可能是更好的解決方案。
下面讓我們看看。裝飾者模式是如何解決上面問題的。
裝飾者模式:動態的將責任加到物件上,若要擴充套件功能,裝飾者提供了比繼承更有彈性的替代方案。
首先,我們先將演播廳和他的裝飾者們分開,讓裝飾者繼承另一個類:
public abstract class Decorater_ex extends Anyting_ex { public abstract String getDescription(); }
讓裝飾者子類重新實現getDescription()即可。
現在我們的思路是:用裝飾者裝飾演播廳,例如,一個帶麥克風和氣球的卡通演播廳,就先讓氣球裝飾卡通演播廳,再讓麥克風裝飾“帶氣球的卡通演播廳”
先讓我們分別實現這3個類:
卡通演播廳:
class CortoonStudio extends Anything_ex { public CortoonStudio() { description="CortonStudio"; } publuc int cost() { return 100; } }
麥克風:
class Microphone extends Decorater_ex { private Anything_ex studio; public Microphone(Anything_ex studio ) { this.studio=studio; } public String getDescription() { return studio.getDescription()+",Microphone"; } public int cost() { return studio.cost()+20; } }
氣球:
class Balloon extends Decorater_ex { private Anything_ex studio; public Balloon(Anything_ex studio ) { this.studio=studio; } public String getDescription() { return studio.getDescription()+",Balloon"; } public int cost() { return studio.cost()+10 ; } }
程式碼:
Anything_ex CortoonStudio =new CortoonStudio(); //一個卡通演播廳物件 CortoonStudio=new Microphone(CortoonStudio); //拿麥克風裝飾 CortoonStudio=new Balloon(CortoonStudio); //拿氣球裝飾 System.out.println(CortoonStudio.getDescription()+"="+CortoonStudio.cost());
輸出結果:
CortonStudio,Microphone,Balloon=130
結果是正確的。
這樣寫很好的解決了上面的問題。
- 1.運用組合進行擴充套件,使當價格改變的時候,只需要修改本身的程式碼。
- 2.面對超類/介面程式設計,使飾品增加種類的時候,並不需要修改被裝飾者的程式碼。
- 3.開放——關閉原則 :程式碼應該對擴充套件開放,對修改關閉。
缺陷:
- 1.子類繁多,影響理解程式碼(java I/O就是裝飾者模式哦。。。)。
- 2.無法應用於需要具體類的場景。
這篇文章到此差不多結束了,作者功力尚淺,文章如有不正之處請讀者指出,海涵。
本文連結:http://www.codeceo.com/article/java-decorator-pattern.html
本文作者:碼農網 – 魯阿皓
[ 原創作品,轉載必須在正文中標註並保留原文連結和作者等資訊。]
相關文章
- java設計模式之裝飾器模式Java設計模式
- Java設計模式之裝飾者模式Java設計模式
- Java學設計模式之裝飾器模式Java設計模式
- 8.java設計模式之裝飾者模式Java設計模式
- java設計模式--裝飾器模式Java設計模式
- 設計模式系列之「裝飾模式」設計模式
- 設計模式之-裝飾器模式設計模式
- 設計模式之裝飾者模式設計模式
- 設計模式之【裝飾器模式】設計模式
- Java設計模式(3)-裝飾者模式Java設計模式
- Java 設計模式(五)《裝飾器模式》Java設計模式
- Java設計模式系列-裝飾器模式Java設計模式
- PHP設計模式之裝飾者模式PHP設計模式
- Go 設計模式之裝飾器模式Go設計模式
- 設計模式之裝飾者模式(二)設計模式
- 設計模式之裝飾者模式(一)設計模式
- 設計模式——裝飾模式設計模式
- 設計模式-裝飾模式設計模式
- 【趣味設計模式系列】之【裝飾器模式】設計模式
- 設計模式之裝飾器模式(decorator pattern)設計模式
- Golang 常見設計模式之裝飾模式Golang設計模式
- PHP設計模式之裝飾器模式(Decorator)PHP設計模式
- 設計模式——裝飾者模式設計模式
- 設計模式----裝飾器模式設計模式
- 設計模式-裝飾器模式設計模式
- 設計模式-裝飾者模式設計模式
- [設計模式]裝飾者模式設計模式
- [設計模式] 裝飾器模式設計模式
- Java進階篇設計模式之五-----外觀模式和裝飾器模式Java設計模式
- 設計模式(十一)----結構型模式之裝飾者模式設計模式
- 裝飾設計模式設計模式
- 設計模式--裝飾模式(Decorator Pattern)設計模式
- 小白設計模式:裝飾者模式設計模式
- Python設計模式-裝飾器模式Python設計模式
- 設計模式-裝飾模式(Decorator Pattern)設計模式
- 設計模式(八)裝飾器模式設計模式
- 軟體設計模式————(裝飾模式)設計模式
- 極簡設計模式-裝飾模式設計模式
- 設計模式(六):裝飾器模式設計模式