java設(shè)計(jì)模式系列之裝飾者模式
何為裝飾者模式 (Decorator)?
動態(tài)地給一個對象添加一些額外的職責(zé)。就增加功能來說,Decorator 模式相比生成子類更為靈活。
一、結(jié)構(gòu)
Component : 定義一個對象接口,可以給這些對象動態(tài)地添加職責(zé)。
interface Component {
public void operation();
}
ConcreteComponent : 實(shí)現(xiàn) Component 定義的接口。
class ConcreteComponent implements Component {
@Override
public void operation() {
System.out.println("初始行為");
}
}
Decorator : 裝飾抽象類,繼承了 Component, 從外類來擴(kuò)展 Component 類的功能,但對于 Component 來說,是無需知道 Decorator 的存在的。
class Decorator implements Component {
// 持有一個 Component 對象,和 Component 形成聚合關(guān)系
protected Component component;
// 傳入要進(jìn)一步修飾的對象
public Decorator(Component component) {
this.component = component;
}
@Override
// 調(diào)用要修飾對象的原方法
public void operation() {
component.operation();
}
}
ConcreteDecorator : 具體的裝飾對象,起到給 Component 添加職責(zé)的功能。
class ConcreteDecoratorA extends Decorator {
private String addedState = "新屬性1";
public ConcreteDecoratorA(Component component) {
super(component);
}
public void operation() {
super.operation();
System.out.println("添加屬性: " + addedState);
}
}
class ConcreteDecoratorB extends Decorator {
public ConcreteDecoratorB(Component component) {
super(component);
}
public void operation() {
super.operation();
AddedBehavior();
}
public void AddedBehavior() {
System.out.println("添加行為");
}
}
測試代碼
public class DecoratorPattern {
public static void main(String[] args) {
Component component = new ConcreteComponent();
component.operation();
System.out.println("======================================");
Decorator decoratorA = new ConcreteDecoratorA(component);
decoratorA.operation();
System.out.println("======================================");
Decorator decoratorB = new ConcreteDecoratorB(decoratorA);
decoratorB.operation();
}
}
運(yùn)行結(jié)果
初始行為 ====================================== 初始行為 添加屬性: 新屬性1 ====================================== 初始行為 添加屬性: 新屬性1 添加行為
二、應(yīng)用場景
1、需要動態(tài)的、透明的為一個對象添加職責(zé),即不影響其他對象。
2、需要動態(tài)的給一個對象添加功能,這些功能可以再動態(tài)的撤銷。
3、需要增加由一些基本功能的排列組合而產(chǎn)生的非常大量的功能,從而使繼承關(guān)系變的不現(xiàn)實(shí)。
4、當(dāng)不能采用生成子類的方法進(jìn)行擴(kuò)充時。一種情況是,可能有大量獨(dú)立的擴(kuò)展,為支持每一種組合將產(chǎn)生大量的子類,使得子類數(shù)目呈爆炸性增長。另一種情況可能是因?yàn)轭惗x被隱藏,或類定義不能用于生成子類。
三、要點(diǎn)
1、裝飾對象和真實(shí)對象有相同的接口。這樣客戶端對象就能以和真實(shí)對象相同的方式和裝飾對象交互。
2、裝飾對象包含一個真實(shí)對象的引用(reference)。
3、裝飾對象接受所有來自客戶端的請求。它把這些請求轉(zhuǎn)發(fā)給真實(shí)的對象。
4、裝飾對象可以在轉(zhuǎn)發(fā)這些請求以前或以后增加一些附加功能。這樣就確保了在運(yùn)行時,不用修改給定對象的結(jié)構(gòu)就可以在外部增加附加的功能。在面向?qū)ο蟮脑O(shè)計(jì)中,通常是通過繼承來實(shí)現(xiàn)對給定類的功能擴(kuò)展。
以上就是關(guān)于java裝飾者模式的相關(guān)內(nèi)容介紹,希望對大家的學(xué)習(xí)有所幫助。
相關(guān)文章
mybatisplus實(shí)現(xiàn)自動填充時間的項(xiàng)目實(shí)踐
在數(shù)據(jù)庫操作中,頻繁設(shè)置創(chuàng)建時間和更新時間字段非常繁瑣,通過使用MyBatis-Plus的自動填充功能,可以簡化操作,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下2024-10-10
SpringMVC中Invalid bound statement (not f
本文主要介紹了SpringMVC中Invalid bound statement (not found)常見報錯問題解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
Springboot通過url訪問本地圖片代碼實(shí)例
這篇文章主要介紹了springboot通過url訪問本地圖片代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-03-03
Mybatis中3種關(guān)聯(lián)關(guān)系的實(shí)現(xiàn)方法示例
這篇文章主要給大家介紹了關(guān)于Mybatis中3種關(guān)聯(lián)關(guān)系的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
一篇文章帶你了解SpringMVC數(shù)據(jù)綁定
這篇文章主要給大家介紹了關(guān)于如何通過一篇文章弄懂Spring MVC的參數(shù)綁定,文中通過示例代碼以及圖文介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端主動推送消息方式
這篇文章主要介紹了SpringBoot整合WebSocket實(shí)現(xiàn)后端向前端主動推送消息方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10

