淺談Java設(shè)計模式系列-裝飾器模式
一、概述
裝飾器模式作用是針對目標方法進行增強,提供新的功能或者額外的功能。
不同于適配器模式和橋接模式,裝飾器模式涉及的是單方,和代理模式相同,而且目標必須是抽象的。
而實際上,裝飾器模式和代理模式的實現(xiàn)方式基本一致,只在目標的存在上有些差別,這個后面我們具體講述。
二、初步分析
上面提到了兩點:
- 涉及的是單方
- 目標是抽象的
我們來想一下,所謂單方主要指的是在整個裝飾器模式中不存在雙方調(diào)用,要解決的也不是雙方調(diào)用的問題,而是解決單方提供對外服務(wù)的問題,這個單方在自行對外提供服務(wù)時,功能不足,或者我們需要額外添加一些新功能,這時就可以使用裝飾器模式,來對這個單方進行增強。
目標抽象的意思是因為我們需要通過實現(xiàn)接口的方式來進行增強,因此目標必須抽象為接口。
三、實例
下面我們用我們生活中的一個例子來說明,我們用房子來作為目標:
房子接口:House
/** * 目標接口:房子 */ public interface House { void output(); }
具體的房子:DonghaoHouse
/** * 房子實現(xiàn)類 */ public class DonghaoHouse implements House { @Override public void output() { System.out.println("這是董浩的房子"); } }
具體的房子:DongliangHouse
/** * 房子實現(xiàn)類 */ 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("這是針對房子的前段裝飾增強"); house.output(); System.out.println("這是針對房子的后段裝飾增強"); } }
測試類:
public class Clienter { public static void main(String[] args) { House donghaoHouse = new DonghaoHouse(); House decorator = new Decorator(donghaoHouse); decorator.output(); } }
執(zhí)行結(jié)果為:
這是針對房子的前段裝飾增強
這是董浩的房子
這是針對房子的后段裝飾增強
四、解析
通過上面的例子我們可以看出,除了測試類外,只剩下接口和實現(xiàn)類了,即使是裝飾器類也是目標接口的一個字類,這更能說明單方的說法,模式中所有的類都屬于目標方。至于目標是抽象的更是如此,只有目標是抽象的,才可以使用裝飾器模式來進行增強。
上面我們說過裝飾器模式與代理模式基本相同,只存在少許差別。
我們需要從概念上了解代理和裝飾的區(qū)別:
- 代理是全權(quán)代理,目標根本不對外,全部由代理類來完成。
- 裝飾是增強,是輔助,目標仍然可以自行對外提供服務(wù),裝飾器只起增強作用。
上面兩點提現(xiàn)到代碼實現(xiàn)中是這樣的:
代理模式
public class Proxy implements House { private House house; public Decorator(){ this.house = new DonghaoHouse(); } @Override public void output() { System.out.println("這是針對目標的前段增強"); house.output(); System.out.println("這是針對目標的后段增強"); } }
裝飾模式
public class Decorator implements House { private House house; public Decorator(House house){ this.house = house; } @Override public void output() { System.out.println("這是針對房子的前段裝飾增強"); house.output(); System.out.println("這是針對房子的后段裝飾增強"); } }
看出來了嗎,裝飾器中持有的目標實例是從構(gòu)造器傳入的,而代理中持有的目標實例是自己創(chuàng)建的。
那么這里又出現(xiàn)一個區(qū)別,代理模式和裝飾器模式雖然都依賴于目標接口,但是代理針對的目標實現(xiàn)類是固定的,而裝飾器模式可以隨意指定,也就是說目標是可以自有擴展的。
五、使用場景
裝飾器模式就是使用在對已有的目標功能存在不足,需要增強時,前提是目標存在抽象接口。
六、總結(jié)
我們要明白代理模式和裝飾器模式的區(qū)別,區(qū)分二者的使用場景,如下圖:
以上所述是小編給大家介紹的Java設(shè)計模式系列-裝飾器模式詳解整合,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
SpringBoot打War包上傳到阿里云的LINUX服務(wù)器的操作方法
這篇文章主要介紹了SpringBoot打War包上傳到阿里云的LINUX服務(wù)器,本文通過圖文并茂的形式給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-02-02淺析JavaWeb項目架構(gòu)之Redis分布式日志隊列
架構(gòu)、分布式、日志隊列,標題自己都看著唬人,其實就是一個日志收集的功能,只不過中間加了一個Redis做消息隊列罷了。下面通過本文給大家分享JavaWeb項目架構(gòu)之Redis分布式日志隊列,感興趣的朋友一起看看吧2018-01-01MyBatis基礎(chǔ)支持DataSource實現(xiàn)源碼解析
這篇文章主要為大家介紹了MyBatis基礎(chǔ)支持DataSource實現(xiàn)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-02-02SpringMVC訪問controller報錯404的解決辦法(總結(jié)超詳細)
純注解配置SpringMVC程序,使用tomcat8.5.95版本啟動,能啟動成功并且訪問index.jsp頁面,但是訪問/save時出現(xiàn)404無法訪問,本文給大家介紹了SpringMVC訪問controller報錯404的解決辦法,文章總結(jié)的非常詳細,需要的朋友可以參考下2024-05-05