Java結構性設計模式中的裝飾器模式介紹使用
裝飾器模式
概述
裝飾器模式(Decorator Pattern)也稱為包裝模式(Wrapper Pattern),屬于結構型模式。
它是指在不改變原有對象的基礎之上,允許向一個現(xiàn)有的對象添加新的功能,同時又不改變其結構,作為現(xiàn)有的類的一個包裝。
這種模式創(chuàng)建一個裝飾類,用來包裝原有的類,并在保持類方法簽名完整性的前提下,提供了額外的功能。
提供了比繼承更有單性的替代方案,進行擴展原有對象的功能。
裝飾器模式的核心是功能擴展。使用裝飾器模式可以透明且動態(tài)地擴展類的功能。
裝飾器模式主要用于誘明且動態(tài)地擴展類的功能。
實現(xiàn)原理
讓裝飾器實現(xiàn)被包裝類相同的接口,使得裝飾器與被擴展類類型一致,并在構造函數(shù)中傳入該接口對象,然后就可以在接口需要實現(xiàn)的方法中在被包裝類對象的現(xiàn)有功能上添加新功能。
由于裝飾器與被包裝類屬于同一類型,且構造函數(shù)的參數(shù)為其實現(xiàn)接口類,因此裝飾器模式具備嵌套擴展功能,因此就能使用裝飾器模式一層層的對最底層被包裝類進行功能擴展。
在JDK中,IO相關包下大量使用裝飾器模式,如BufferedReader、InputStream、OutputStream等類
主要角色
裝飾器模式主要包含4種角色
1.抽象組件(Component)
抽象組件可以是一個接口或者抽象類,其充當被裝飾類的原始對象,規(guī)定了被裝飾對象的行為。
2.具體組件(ConcreteComponent)
具體組件實現(xiàn)/繼承抽象組件的一個具體對象,即被裝飾對象。
3.抽象裝飾器(Decorator)
通用的裝飾具體組件的裝飾器,其內部必然有一個屬性指向抽象組件;其實現(xiàn)一般是一個抽象類,主要是為了讓其子類按照其構造形式傳入一個抽象組件,這是強制的通用行為。
如果系統(tǒng)中裝飾邏輯單一,并不需要實現(xiàn)許多裝飾器,那么可以直接省略該類,而直接實現(xiàn)一個具體裝飾器即可。
4.具體裝飾器(ConcreteDecorator)
抽象裝飾器的具體實現(xiàn)類,理論上,每個具體組件都擴展了抽象組件對象的一種功能。
應用場景
1.用于擴展一個類的功能或給一個類添加附加職責。
2.動態(tài)的給一個對象添加功能,這些功能可以再動態(tài)的澈銷。
3.需要為一批的兄弟類進行改裝或加裝功能。
優(yōu)缺點
優(yōu)點:
1.裝飾器是繼承的補充,比繼承靈活,不改變原有對象的情況下動態(tài)地給一個對象擴展功能,即插即用。
2.裝飾器完全遵守開閉原則。
缺點:
1.會出現(xiàn)更多的代碼,更多的類,增加程序復雜性。
2.通過使用不同裝飾類以及這些裝飾類的排列組合,可以實現(xiàn)不同效果。
3.動態(tài)裝飾時,多層裝飾時會更復雜。
裝飾器模式的基本使用
創(chuàng)建抽象組件
創(chuàng)建Phone抽象類
public abstract class Phone { public abstract String call(); public abstract double price(); }
具體組件
創(chuàng)建最基本具有打電話功能的手機
public class BasePhone extends Phone { @Override public String call() { return "BasePhone call"; } @Override public double price() { return 0.1; } }
抽象裝飾器
創(chuàng)建一個抽象裝飾器來擴展該只具備基本功能的手機
public abstract class PhoneDecorator extends Phone { private Phone phone; public PhoneDecorator(Phone phone) { this.phone = phone; } @Override public String call() { return phone.call(); } @Override public double price() { return phone.price(); } /** * 擴展功能 */ public abstract void sendMsg(); }
具體裝飾器
public class SatellitePhoneDecorator extends PhoneDecorator{ public SatellitePhoneDecorator(Phone phone) { super(phone); } public void sendMsg() { System.out.println("PhoneCallDecorator sendMsg"); } @Override public String call() { return "SatellitePhone call"; } @Override public double price() { return super.price()+100; } }
客戶端調用
public static void main(String[] args) { // 創(chuàng)建需要被裝飾的原始對象(即要被裝飾的對象) Phone phone = new BasePhone(); System.out.println("使用: "+phone.call()+" 方式打電話,每分鐘單價:" + phone.price()); // 給對象透明的增加額外功能并調用 PhoneDecorator phoneDecorator = new SatellitePhoneDecorator(phone); System.out.println("使用: "+phoneDecorator.call()+" 方式打電話,每分鐘單價:" + phoneDecorator.price()); // 裝飾器也可以裝飾具體的裝飾對象,相當于給對象在增加的功能基礎上在添加功能,這里體現(xiàn)在單價100.1基礎上再+100 PhoneDecorator satellitePhoneDecorator = new SatellitePhoneDecorator(phoneDecorator); System.out.println("使用: "+satellitePhoneDecorator.call()+" 方式打電話,每分鐘單價:" + satellitePhoneDecorator.price()); satellitePhoneDecorator.sendMsg(); }
使用: BasePhone call 方式打電話,每分鐘單價:0.1
使用: SatellitePhone call 方式打電話,每分鐘單價:100.1
使用: SatellitePhone call 方式打電話,每分鐘單價:200.1
PhoneCallDecorator sendMsg
到此這篇關于Java結構性設計模式中的裝飾器模式介紹使用的文章就介紹到這了,更多相關Java裝飾器模式內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Spring?Boot?使用?SSE?方式向前端推送數(shù)據(jù)詳解
這篇文章主要介紹了Spring?Boot?使用SSE方式向前端推送數(shù)據(jù)詳解,SSE簡單的來說就是服務器主動向前端推送數(shù)據(jù)的一種技術,它是單向的,也就是說前端是不能向服務器發(fā)送數(shù)據(jù)的2022-08-08Springboot詳解實現(xiàn)食品倉庫管理系統(tǒng)流程
這是一個使用Springboot開發(fā)的食品倉庫管理系統(tǒng),是為商家提供商品貨物進銷存的信息化管理系統(tǒng),具有一個倉庫管理系統(tǒng)該有的所有功能,感興趣的朋友快來看看吧2022-06-06Zookeeper如何實現(xiàn)分布式服務配置中心詳解
Zookeeper在實際使用場景很多,比如配置中心,分布式鎖,注冊中心等,下面這篇文章主要給大家介紹了關于Zookeeper如何實現(xiàn)分布式服務配置中心的相關資料,需要的朋友可以參考下2021-11-11IDEA2020 Plugins不能用的解決辦法及Plugins 搜索不了插件的問題
這篇文章主要介紹了IDEA2020 Plugins不能用的解決辦法,文中給大家介紹了Intellij IDEA 2020.1 的Plugins 搜索不了插件,連接超時的問題,本文給大家介紹的非常詳細,需要的朋友可以參考下2020-06-06