Java中设计模式之装饰者模式-2
裝飾者模式:
動態地將責任附加到對象上。若要擴展功能,裝飾者提供了比繼承更加有彈性的替代方案。
裝飾者核心:實現功能組合
繼承與組合區別:
繼承
繼承是給一個類添加行為的比較有效的途徑。通過使用繼承,可以使得子類在擁有自身方法的同時,還可以擁有父類的方法。但是使用繼承是靜態的,在編譯的時候就已經決定了子類的行為,我們不便于控制增加行為的方式和時機。
組合
組合即將一個對象嵌入到另一個對象中,由另一個對象來決定是否引用該對象來擴展自己的行為。這是一種動態的方式,我們可以在應用程序中動態的控制。
與繼承相比,組合關系的優勢就在于不會破壞類的封裝性,且具有較好的松耦合性,可以使系統更加容易維護。但是它的缺點就在于要創建比繼承更多的對象。
裝飾者模式優點
一句話:在原有的基礎上 ,增加功能 ,提高效率
1、裝飾者模式可以提供比繼承更多的靈活性
2、可以通過一種動態的方式來擴展一個對象的功能,在運行時選擇不同的裝飾器,從而實現不同的行為。
3、通過使用不同的具體裝飾類以及這些裝飾類的排列組合,可以創造出很多不同行為的組合。可以使用多個具體裝飾類來裝飾同一對象,得到功能更為強大的對象。
4、具體構件類與具體裝飾類可以獨立變化,用戶可以根據需要增加新的具體構件類和具體裝飾類,在使用時再對其進行組合,原有代碼無須改變,符合“開閉原則”。
裝飾者模式缺點
一句話:繁瑣
1、會產生很多的小對象,增加了系統的復雜性
2、這種比繼承更加靈活機動的特性,也同時意味著裝飾模式比繼承更加易于出錯,排錯也很困難,對于多次裝飾的對象,調試時尋找錯誤可能需要逐級排查,較為煩瑣。
裝飾者應用場景
1、在不影響其他對象的情況下,以動態、透明的方式給單個對象添加職責。
2、需要動態地給一個對象增加功能,這些功能也可以動態地被撤銷。 當不能采用繼承的方式對系統進行擴充或者采用繼承不利于系統擴展和維護時。
個人理解:
裝飾者模式是指在繼承父類后,重寫父類方法時,不改變父類中該方法的原有功能,只是在該功能基礎上添加自己想要擴充的功能。
一句話:父類原有功能不變,子類再添加其他功能
簡單實例:
父類
package 設計模式之裝飾者模式;public class Father {public void run(){System.out.println("跑步...");} }子類:
在子類中重寫run方法時,不改變父類的原有功能,并根據需要添加自己的功能。這里的裝飾并不復雜,不存在多層裝飾,所以在子類中創建一個父類屬性是多余的,但在多層裝飾中,這是必要的。
測試類:
package 設計模式之裝飾者模式;public class Test {public static void main(String[] args){Father father=new Father();father.run();System.out.println("son:");Son son = new Son(father);son.run();} }結果:
多層裝飾實例
借鑒實例,來自http://www.cnblogs.com/xinye/p/3910149.html
邏輯分析圖:
1.裝飾者基類(被操作的對象)
package com.xinye.test.decoration; /*** 食物基類* @author xinye**/ public abstract class Food {protected String desc;public abstract String getDesc(); }2.被操作對象具體類
雞肉
package com.xinye.test.decoration; /*** 雞肉* @author xinye**/ public class Chicken extends Food {public Chicken(){desc = "雞肉";}@Overridepublic String getDesc() {return desc;}}鴨肉
package com.xinye.test.decoration; /*** 鴨肉* @author xinye**/ public class Duck extends Food {public Duck(){desc = "鴨肉";}@Overridepublic String getDesc() {return desc;}}3.裝飾者基類(操作類,對對象實現什么操作)
package com.xinye.test.decoration; /*** * @author xinye**/ public abstract class FoodDecoration extends Food {@Overridepublic abstract String getDesc();}4.具體操作類
蒸-裝飾者
package com.xinye.test.decoration; /*** 蒸食物* @author xinye**/ public class SteamedFood extends FoodDecoration {private Food food;public SteamedFood(Food f){this.food = f;}@Overridepublic String getDesc() {return getDecoration() + food.getDesc();}private String getDecoration(){return "蒸";} }烤-裝飾者
package com.xinye.test.decoration; /*** 烤食物* @author xinye**/ public class RoastFood extends FoodDecoration {private Food food;public RoastFood(Food f){this.food = f;}@Overridepublic String getDesc() {return getDecoration() + food.getDesc();}private String getDecoration(){return "烤";} }5.測試類(客戶端)
package com.xinye.test.decoration; /*** 客戶端* @author xinye**/ public class Client {public static void main(String[] args) {// 測試單純的食物Food f1 = new Chicken();System.out.println(f1.getDesc());System.out.println("----------------------");// 測試單重修飾的食物RoastFood rf = new RoastFood(f1);System.out.println(rf.getDesc());System.out.println("----------------------");// 測試多重修飾的食物SteamedFood sf = new SteamedFood(rf);System.out.println(sf.getDesc());} }執行結果:
雞肉
烤雞肉
蒸烤雞肉
總結
以上是生活随笔為你收集整理的Java中设计模式之装饰者模式-2的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java中设计模式之单例设计模式-1
- 下一篇: Java中设计模式之生产者消费者模式-3