Java設(shè)計模式中裝飾者模式應(yīng)用詳解
編程是一門藝術(shù),大批量的改動顯然是非常丑陋的做法,用心的琢磨寫的代碼讓它變的更美觀。
在現(xiàn)實生活中,常常需要對現(xiàn)有產(chǎn)品增加新的功能或美化其外觀,如房子裝修、相片加相框等,都是裝飾器模式。
在軟件開發(fā)過程中,有時想用一些現(xiàn)存的組件。這些組件可能只是完成了一些核心功能。但在不改變其結(jié)構(gòu)的情況下,可以動態(tài)地擴展其功能。所有這些都可以釆用裝飾器模式來實現(xiàn)。
1.裝飾器模式(Decorator)的定義
裝飾器模式:是指在不改變現(xiàn)有對象結(jié)構(gòu)的情況下,動態(tài)地給該對象增加一些職責(zé)(即增加其額外功能)的模式,它屬于對象結(jié)構(gòu)型模式。
2.裝飾者設(shè)計模式的優(yōu)點與不足
裝飾者設(shè)計模式優(yōu)點:
- 裝飾器是繼承的有力補充,比繼承靈活,在不改變原有對象的情況下,動態(tài)的給一個對象擴展功能,即插即用
- 通過使用不用裝飾類及這些裝飾類的排列組合,可以實現(xiàn)不同效果
- 裝飾器模式完全遵守開閉原則
其主要缺點是:裝飾器模式會增加許多子類,過度使用會增加程序得復(fù)雜性。
3.裝飾器模式的實現(xiàn)思路
通常情況下,擴展一個類的功能會使用繼承方式來實現(xiàn)。但繼承具有靜態(tài)特征,耦合度高,并且隨著擴展功能的增多,子類會很膨脹。如果使用組合關(guān)系來創(chuàng)建一個包裝對象(即裝飾對象)來包裹真實對象,并在保持真實對象的類結(jié)構(gòu)不變的前提下,為其提供額外的功能,這就是裝飾器模式的目標(biāo)。
4.裝飾者代碼示例
實例場景介紹:采摘水果,然后進行包裝,這是主流程,然后需要對包裝進行功能增強,比如:增加防偽標(biāo)識、長途加固、標(biāo)記加急。
/** * 包裝接口 */ public interface Bag { void pack(); } /** * 這個是裝飾者的基類 */ public abstract class BagDecorator implements Bag { /** * 維持一個對 抽象構(gòu)件對象的引用 * 這個是想要增強的功能對象 將想要增強的功能對象傳進來,然后才能進行功能增強 */ private Bag bag; /** * 注入一個抽象構(gòu)件類型的對象 * 將之前的對象傳遞進來,進行功能增強 * @param bag */ public BagDecorator(Bag bag) { this.bag = bag; } @Override public void pack() { bag.pack(); } } /** * 增加防偽標(biāo)識 */ public class CheckedBagDecorator extends BagDecorator{ public CheckedBagDecorator(Bag bag) { super(bag); } @Override public void pack() { super.pack(); checked(); } public void checked() { System.out.println("打印上防偽標(biāo)識"); } } /** * 加固增強 */ public class ReinforceBagDecorator extends BagDecorator { public ReinforceBagDecorator(Bag bag) { super(bag); } public void pack() { super.pack(); reinforce(); } public void reinforce() { System.out.println("加固了包裝"); } } /** * 加急功能增強 */ public class SpeedDecorator extends BagDecorator { public SpeedDecorator(Bag bag) { super(bag); } @Override public void pack() { super.pack(); speedy(); } public void speedy() { System.out.println("打上加急標(biāo)識"); } } public static void main(String[] args){ AbstractFactory factory = new AppleFactory(); /*得到水果*/ Fruit fruit = factory.getFruit(); fruit.draw(); /*得到包裝*/ Bag bag = factory.getBag(); /*下面是對包裝進行裝飾的過程(也就是功能增強的過程)*/ /*現(xiàn)需要增加防偽標(biāo)識*/ bag = new CheckedBagDecorator(bag); /*加固功能*/ bag = new ReinforceBagDecorator(bag); /*加急功能*/ bag = new SpeedDecorator(bag); bag.pack(); }
BagDecorator:功能增強基類,實現(xiàn)了待增強功能的行為接口,并持有一個包裝接口成員變量,這個變量通過構(gòu)造方法注入進來,這個成員變量就是上一個增強之后的結(jié)果,一定要在上一個增強的結(jié)果之上進行功能增強,否則,就將之前的功能丟失了,所以這個成員變量很關(guān)鍵。
還有就是每次進行包裝pack的時候,一定要先調(diào)用super方法,先之前之前的包裝,然后再進行增強。
5.裝飾器模式的應(yīng)用場景
裝飾器模式通常在以下幾種情況使用:
- 當(dāng)需要給一個現(xiàn)有類添加附加職責(zé),而又不能采用生成子類的方法進行擴充時。例如,該類被隱藏或者該類是終極類或者采用繼承方式會產(chǎn)生大量的子類。
- 當(dāng)需要通過對現(xiàn)有的一組基本功能進行排列組合而產(chǎn)生非常多的功能時,采用繼承關(guān)系很難實現(xiàn),而采用裝飾器模式卻很好實現(xiàn)。
- 當(dāng)對象的功能要求可以動態(tài)地添加,也可以再動態(tài)地撤銷時。
裝飾者設(shè)計模式,在Java中非常經(jīng)典的例子是:
InputStream 的子類 FilterInputStream,OutputStream 的子類 FilterOutputStream,Reader 的子類 BufferedReader 以及 FilterReader,還有 Writer 的子類 BufferedWriter、FilterWriter 以及 PrintWriter 等,它們都是抽象裝飾類。
到此這篇關(guān)于Java設(shè)計模式中裝飾者模式應(yīng)用詳解的文章就介紹到這了,更多相關(guān)Java裝飾者模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
實踐講解SpringBoot自定義初始化Bean+HashMap優(yōu)化策略模式
本篇講解了SpringBoot自定義初始化Bean+HashMap優(yōu)化策略模式,通過實踐的方式更通俗易懂,對此不了解的同學(xué)跟著小編往下看吧2021-09-09Java數(shù)據(jù)結(jié)構(gòu)之對象的比較
比較對象是面向?qū)ο缶幊陶Z言的一個基本特征,下面這篇文章主要給大家介紹了關(guān)于Java數(shù)據(jù)結(jié)構(gòu)之對象的比較,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02java8 stream 由一個list轉(zhuǎn)化成另一個list案例
這篇文章主要介紹了java8 stream 由一個list轉(zhuǎn)化成另一個list案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08基于Redis分布式鎖Redisson及SpringBoot集成Redisson
這篇文章主要介紹了基于Redis分布式鎖Redisson及SpringBoot集成Redisson,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價值,需要的小小伙伴可以參考一下2022-09-09SpringBoot+JWT實現(xiàn)單點登錄完美解決方案
單點登錄是一種統(tǒng)一認(rèn)證和授權(quán)機制,指在多個應(yīng)用系統(tǒng)中,用戶只需要登錄一次就可以訪問所有相互信任的系統(tǒng),不需要重新登錄驗證,這篇文章主要介紹了SpringBoot+JWT實現(xiàn)單點登錄解決方案,需要的朋友可以參考下2023-07-07SpringBoot實現(xiàn)連接nacos并支持多環(huán)境部署
這篇文章主要介紹了SpringBoot實現(xiàn)連接nacos并支持多環(huán)境部署方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06Presto自定義函數(shù)@SqlNullable引發(fā)問題詳解
這篇文章主要為大家介紹了Presto自定義函數(shù)@SqlNullable引發(fā)問題詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12Java基于外觀模式實現(xiàn)美食天下食譜功能實例詳解
這篇文章主要介紹了Java基于外觀模式實現(xiàn)美食天下食譜功能,較為詳細(xì)的講述了外觀模式的概念、原理并結(jié)合實例形似詳細(xì)分析了Java基于外觀模式實現(xiàn)美食天下食譜功能的具體操作步驟與相關(guān)注意事項,需要的朋友可以參考下2018-05-05