淺談Java設(shè)計(jì)模式系列-裝飾器模式
一、概述
裝飾器模式作用是針對(duì)目標(biāo)方法進(jìn)行增強(qiáng),提供新的功能或者額外的功能。
不同于適配器模式和橋接模式,裝飾器模式涉及的是單方,和代理模式相同,而且目標(biāo)必須是抽象的。
而實(shí)際上,裝飾器模式和代理模式的實(shí)現(xiàn)方式基本一致,只在目標(biāo)的存在上有些差別,這個(gè)后面我們具體講述。
二、初步分析
上面提到了兩點(diǎn):
- 涉及的是單方
- 目標(biāo)是抽象的
我們來(lái)想一下,所謂單方主要指的是在整個(gè)裝飾器模式中不存在雙方調(diào)用,要解決的也不是雙方調(diào)用的問(wèn)題,而是解決單方提供對(duì)外服務(wù)的問(wèn)題,這個(gè)單方在自行對(duì)外提供服務(wù)時(shí),功能不足,或者我們需要額外添加一些新功能,這時(shí)就可以使用裝飾器模式,來(lái)對(duì)這個(gè)單方進(jìn)行增強(qiáng)。
目標(biāo)抽象的意思是因?yàn)槲覀冃枰ㄟ^(guò)實(shí)現(xiàn)接口的方式來(lái)進(jìn)行增強(qiáng),因此目標(biāo)必須抽象為接口。
三、實(shí)例
下面我們用我們生活中的一個(gè)例子來(lái)說(shuō)明,我們用房子來(lái)作為目標(biāo):
房子接口:House
/**
* 目標(biāo)接口:房子
*/
public interface House {
void output();
}
具體的房子:DonghaoHouse
/**
* 房子實(shí)現(xiàn)類(lèi)
*/
public class DonghaoHouse implements House {
@Override
public void output() {
System.out.println("這是董浩的房子");
}
}
具體的房子:DongliangHouse
/**
* 房子實(shí)現(xiàn)類(lèi)
*/
public class DongliangHouse implements House {
@Override
public void output() {
System.out.println("這是董量的房子");
}
}
裝飾器:Decorator
public class Decorator implements House {
private House house;
public Decorator(House house){
this.house = house;
}
@Override
public void output() {
System.out.println("這是針對(duì)房子的前段裝飾增強(qiáng)");
house.output();
System.out.println("這是針對(duì)房子的后段裝飾增強(qiáng)");
}
}
測(cè)試類(lèi):
public class Clienter {
public static void main(String[] args) {
House donghaoHouse = new DonghaoHouse();
House decorator = new Decorator(donghaoHouse);
decorator.output();
}
}
執(zhí)行結(jié)果為:
這是針對(duì)房子的前段裝飾增強(qiáng)
這是董浩的房子
這是針對(duì)房子的后段裝飾增強(qiáng)
四、解析
通過(guò)上面的例子我們可以看出,除了測(cè)試類(lèi)外,只剩下接口和實(shí)現(xiàn)類(lèi)了,即使是裝飾器類(lèi)也是目標(biāo)接口的一個(gè)字類(lèi),這更能說(shuō)明單方的說(shuō)法,模式中所有的類(lèi)都屬于目標(biāo)方。至于目標(biāo)是抽象的更是如此,只有目標(biāo)是抽象的,才可以使用裝飾器模式來(lái)進(jìn)行增強(qiáng)。
上面我們說(shuō)過(guò)裝飾器模式與代理模式基本相同,只存在少許差別。
我們需要從概念上了解代理和裝飾的區(qū)別:
- 代理是全權(quán)代理,目標(biāo)根本不對(duì)外,全部由代理類(lèi)來(lái)完成。
- 裝飾是增強(qiáng),是輔助,目標(biāo)仍然可以自行對(duì)外提供服務(wù),裝飾器只起增強(qiáng)作用。
上面兩點(diǎn)提現(xiàn)到代碼實(shí)現(xiàn)中是這樣的:
代理模式
public class Proxy implements House {
private House house;
public Decorator(){
this.house = new DonghaoHouse();
}
@Override
public void output() {
System.out.println("這是針對(duì)目標(biāo)的前段增強(qiáng)");
house.output();
System.out.println("這是針對(duì)目標(biāo)的后段增強(qiáng)");
}
}
裝飾模式
public class Decorator implements House {
private House house;
public Decorator(House house){
this.house = house;
}
@Override
public void output() {
System.out.println("這是針對(duì)房子的前段裝飾增強(qiáng)");
house.output();
System.out.println("這是針對(duì)房子的后段裝飾增強(qiáng)");
}
}
看出來(lái)了嗎,裝飾器中持有的目標(biāo)實(shí)例是從構(gòu)造器傳入的,而代理中持有的目標(biāo)實(shí)例是自己創(chuàng)建的。
那么這里又出現(xiàn)一個(gè)區(qū)別,代理模式和裝飾器模式雖然都依賴(lài)于目標(biāo)接口,但是代理針對(duì)的目標(biāo)實(shí)現(xiàn)類(lèi)是固定的,而裝飾器模式可以隨意指定,也就是說(shuō)目標(biāo)是可以自有擴(kuò)展的。
五、使用場(chǎng)景
裝飾器模式就是使用在對(duì)已有的目標(biāo)功能存在不足,需要增強(qiáng)時(shí),前提是目標(biāo)存在抽象接口。
六、總結(jié)
我們要明白代理模式和裝飾器模式的區(qū)別,區(qū)分二者的使用場(chǎng)景,如下圖:

以上所述是小編給大家介紹的Java設(shè)計(jì)模式系列-裝飾器模式詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
SpringBoot打War包上傳到阿里云的LINUX服務(wù)器的操作方法
這篇文章主要介紹了SpringBoot打War包上傳到阿里云的LINUX服務(wù)器,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02
淺析JavaWeb項(xiàng)目架構(gòu)之Redis分布式日志隊(duì)列
架構(gòu)、分布式、日志隊(duì)列,標(biāo)題自己都看著唬人,其實(shí)就是一個(gè)日志收集的功能,只不過(guò)中間加了一個(gè)Redis做消息隊(duì)列罷了。下面通過(guò)本文給大家分享JavaWeb項(xiàng)目架構(gòu)之Redis分布式日志隊(duì)列,感興趣的朋友一起看看吧2018-01-01
java實(shí)現(xiàn)砸金蛋抽獎(jiǎng)功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)砸金蛋抽獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-11-11
JavaEE在線(xiàn)人數(shù)管理系統(tǒng)
這篇文章主要為大家分享了JavaEE在線(xiàn)人數(shù)管理系統(tǒng),顯示在線(xiàn)人數(shù)、在線(xiàn)人詳細(xì)信息、管理員踢人等功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
Struts中action線(xiàn)程安全問(wèn)題解析
這篇文章主要介紹了Struts中action線(xiàn)程安全問(wèn)題解析,涉及實(shí)例代碼,還是挺不錯(cuò)的,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10
MyBatis基礎(chǔ)支持DataSource實(shí)現(xiàn)源碼解析
這篇文章主要為大家介紹了MyBatis基礎(chǔ)支持DataSource實(shí)現(xiàn)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-02-02
java項(xiàng)目構(gòu)建Gradle的使用教程
這篇文章主要為大家介紹了java項(xiàng)目構(gòu)建Gradle的使用教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-03-03
SpringMVC訪問(wèn)controller報(bào)錯(cuò)404的解決辦法(總結(jié)超詳細(xì))
純注解配置SpringMVC程序,使用tomcat8.5.95版本啟動(dòng),能啟動(dòng)成功并且訪問(wèn)index.jsp頁(yè)面,但是訪問(wèn)/save時(shí)出現(xiàn)404無(wú)法訪問(wèn),本文給大家介紹了SpringMVC訪問(wèn)controller報(bào)錯(cuò)404的解決辦法,文章總結(jié)的非常詳細(xì),需要的朋友可以參考下2024-05-05

