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