设计模式-Decorator模式
目錄
- 一個(gè)例子(貪玩藍(lán)月)
- 傳統(tǒng)繼承實(shí)現(xiàn)
- 裝飾器模式實(shí)現(xiàn)
- 對(duì)比
- 總結(jié)
Decorator(裝飾器)模式屬于結(jié)構(gòu)型模式。
比如當(dāng)其需要三種不同的附加特性,可以為其創(chuàng)建三個(gè)派生類。但是若它還需要同時(shí)具有其中兩種特性或者是各種特性的任意組合的時(shí)候,類繼承的方法就不再適合了。
它允許向一個(gè)現(xiàn)有的對(duì)象不通過(guò)繼承來(lái)添加新的功能,同時(shí)又不改變其結(jié)構(gòu)。
一個(gè)例子(貪玩藍(lán)月)
前一陣子張家輝代言的《貪玩藍(lán)月》廣告火了,“我系喳喳輝,是兄弟就來(lái)砍我~”被洗腦到現(xiàn)在,正好用這個(gè)游戲來(lái)解釋一下裝飾器模式。
玩游戲的人都知道這種類傳奇的游戲核心玩法就是買(mǎi)裝備,打怪,升級(jí),買(mǎi)裝備這樣反復(fù)。
剛注冊(cè)賬號(hào)進(jìn)入游戲的玩家假設(shè)只有一條大褲衩,價(jià)值5金幣,隨著刷怪升級(jí),身上的裝備也在一件件增多,這時(shí)候我們需要知道身上的裝備價(jià)值多少金幣。
定義玩家
public interface Gamer {/*** 獲取目前的裝備* @return*/String getEquip();/*** 獲取目前身上裝備的價(jià)格* @return*/int getPrice(); }定義具體的法師職業(yè)玩家
public class MasterGamer implements Gamer {/*** 獲取目前的裝備** @return*/@Overridepublic String getEquip() {return "大褲衩";}/*** 獲取目前身上裝備的價(jià)格** @return*/@Overridepublic int getPrice() {return 5;} }新法師玩家出門(mén)只有大褲衩,裝備全靠打。
傳統(tǒng)繼承實(shí)現(xiàn)
裝備“法師權(quán)杖”
public class TruncheonMasterGamer extends MasterGamer{/*** 獲取目前的裝備** @return*/@Overridepublic String getEquip() {return super.getEquip()+",法師權(quán)杖";}/*** 獲取目前身上裝備的價(jià)格** @return*/@Overridepublic int getPrice() {return super.getPrice()+50;} }繼續(xù)裝備“魔法斗篷”
public class CloakTruncheonMasterGamer extends TruncheonMasterGamer{/*** 獲取目前的裝備** @return*/@Overridepublic String getEquip() {return super.getEquip()+",魔法斗篷";}/*** 獲取目前身上裝備的價(jià)格** @return*/@Overridepublic int getPrice() {return super.getPrice()+80;} }注意,這里是在之前已經(jīng)裝備了“法師權(quán)杖”之上去繼承。
計(jì)算裝備價(jià)格
CloakTruncheonMasterGamer gamer = new CloakTruncheonMasterGamer(); System.out.println("當(dāng)前裝備:"+gamer.getEquip()+"\n裝備總價(jià)值:"+gamer.getPrice());輸出結(jié)果
當(dāng)前裝備:大褲衩,法師權(quán)杖,魔法斗篷 裝備總價(jià)值:135裝飾器模式實(shí)現(xiàn)
聲明通用裝飾器基類“裝備”
具體裝飾器“法師權(quán)杖”
public class Truncheon extends Equip {public Truncheon(Gamer gamer) {super(gamer);}/*** 獲取目前的裝備** @return*/@Overridepublic String getEquip() {return super.getEquip()+",法師權(quán)杖";}/*** 獲取目前身上裝備的價(jià)格** @return*/@Overridepublic int getPrice() {return super.getPrice()+50;} }具體裝飾器“魔法斗篷”
public class Cloak extends Equip {public Cloak(Gamer gamer) {super(gamer);}/*** 獲取目前的裝備** @return*/@Overridepublic String getEquip() {return super.getEquip()+",魔法斗篷";}/*** 獲取目前身上裝備的價(jià)格** @return*/@Overridepublic int getPrice() {return super.getPrice()+80;} }計(jì)算裝備價(jià)格
//創(chuàng)建一個(gè)法師玩家 Gamer gamer = new MasterGamer(); //給法師玩家裝備法師權(quán)杖 gamer = new Truncheon(gamer); //給法師玩家裝備魔法斗篷 gamer = new Cloak(gamer); System.out.println("當(dāng)前裝備:"+gamer.getEquip()+"\n裝備總價(jià)值:"+gamer.getPrice());輸出結(jié)果
當(dāng)前裝備:大褲衩,法師權(quán)杖,魔法斗篷 裝備總價(jià)值:135對(duì)比
上面例子比較簡(jiǎn)單,傳統(tǒng)繼承實(shí)現(xiàn)和裝飾器模式實(shí)現(xiàn)區(qū)別不是很明顯,但仔細(xì)思考還是會(huì)發(fā)現(xiàn)一些區(qū)別:
- 傳統(tǒng)繼承實(shí)現(xiàn)不自由,沒(méi)有“組件化”特性。玩家的裝備是可以隨意組合,隨意拆卸的,而這種特性對(duì)于繼承來(lái)說(shuō)只能通過(guò)各種各樣的子類組合來(lái)實(shí)現(xiàn)。就像上面的例子,裝備“法師權(quán)杖”和“魔法斗篷”需要在擁有“法師權(quán)杖”的基礎(chǔ)上再去繼承。
- 裝飾器模式實(shí)現(xiàn),使得附屬屬性和主體分開(kāi),而又不單獨(dú)存在(Equip類里面聲明了Gamer對(duì)象)。裝備和玩家是分開(kāi)的,可以給玩家單獨(dú)裝備任何裝備,也可以隨意卸下裝備。
總結(jié)
這種設(shè)計(jì)模式下不僅可以擴(kuò)展一個(gè)類的功能,也可以動(dòng)態(tài)增加功能,動(dòng)態(tài)撤銷。但缺點(diǎn)就是多層裝飾使用起來(lái)相對(duì)比較復(fù)雜。本質(zhì)是將具體功能職責(zé)劃分(例如區(qū)分核心組件以及附加屬性職責(zé))減少子類直接繼承父類的耦合性。
你可以在這里獲取相關(guān)代碼:設(shè)計(jì)模式-Decorator模式
轉(zhuǎn)載于:https://www.cnblogs.com/xuxiaojian/p/11468734.html
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的设计模式-Decorator模式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: ECharts简单入门demo
- 下一篇: 网络基础 + 简易服务端和客户端