【設計模式】裝飾器模式(結構型)??

文章目錄

  • 1.概念
    • 1.1 什么是裝飾器模式
    • 1.2 優點與缺點
  • 2.實現方式
  • 3. Java 哪些地方用到了裝飾器模式
  • 4. Spring 哪些地方用到了裝飾器模式

1.概念

1.1 什么是裝飾器模式

它允許用戶在不修改現有對象的代碼的情況下向對象添加新的功能;這種模式是通過創建一個包含該對象的包裝對象來實現的,從而擴展該對象的功能。

1.2 優點與缺點

優點:
1.靈活性和擴展性:裝飾器模式允許在運行時向對象添加新的行為,提供了比繼承更大的靈活性。
2.遵守開閉原則:裝飾器模式允許向系統添加新的行為而不需要修改現有代碼,這符合開閉原則(軟件實體應該對擴展開放,對修改關閉)。
3.代碼復用:裝飾器可以被多個對象共享,這減少了代碼的重復,提高了代碼復用性。
4.對象功能增強:在不改變原有對象的情況下,可以有選擇性地增強對象的功能。
5.組合優于繼承:裝飾器模式使用對象組合而不是繼承來擴展功能,這有助于避免繼承層次可能帶來的復雜性和脆弱性。
缺點:
1.增加復雜性:裝飾器模式可能會增加系統的復雜性,因為需要創建多個小對象來表示不同的功能。2.調試困難:由于裝飾器可以嵌套使用,調試和理解運行時的行為可能會變得更加困難。
3.性能問題:裝飾器模式可能會引入額外的性能開銷,因為需要創建額外的對象,并且可能需要通過多個裝飾器來解析方法調用。
4.設計復雜:如果使用不當,裝飾器模式可能會導致設計變得復雜,特別是當裝飾器之間的關系變得復雜時。
5.接口限制:裝飾器模式要求裝飾器和被裝飾的對象實現相同的接口,這在某些情況下可能是不切實際的。

2.實現方式

①定義接口

public interface Beverage {String getDescription();double cost();
}

②創建一個實現了Beverage接口的具體類SimpleCoffee

public class SimpleCoffee implements Beverage {@Overridepublic String getDescription() {return "Simple Coffee";}@Overridepublic double cost() {return 1.0;}
}

③定義一個裝飾器類CondimentDecorator,它也實現了Beverage接口,并持有一個Beverage對象的引用:

public abstract class CondimentDecorator implements Beverage {protected Beverage beverage;public CondimentDecorator(Beverage beverage) {this.beverage = beverage;}public abstract String getDescription();
}

④創建具體的裝飾器類,比如Milk、Sugar和Chocolate,它們都擴展了CondimentDecorator并添加了各自的成本和描述:

public class Milk extends CondimentDecorator {public Milk(Beverage beverage) {super(beverage);}@Overridepublic String getDescription() {return beverage.getDescription() + ", Milk";}@Overridepublic double cost() {return beverage.cost() + 0.5;}
}public class Sugar extends CondimentDecorator {public Sugar(Beverage beverage) {super(beverage);}@Overridepublic String getDescription() {return beverage.getDescription() + ", Sugar";}@Overridepublic double cost() {return beverage.cost() + 0.1;}
}public class Chocolate extends CondimentDecorator {public Chocolate(Beverage beverage) {super(beverage);}@Overridepublic String getDescription() {return beverage.getDescription() + ", Chocolate";}@Overridepublic double cost() {return beverage.cost() + 0.3;}
}

⑤ 使用

public class DecoratorDemo {public static void main(String[] args) {Beverage coffee = new SimpleCoffee();System.out.println(coffee.getDescription() + " $" + coffee.cost());coffee = new Milk(coffee);coffee = new Sugar(coffee);coffee = new Chocolate(coffee);System.out.println(coffee.getDescription() + " $" + coffee.cost());}
}

3. Java 哪些地方用到了裝飾器模式

Java I/O 流
Java的I/O庫廣泛使用了裝飾器模式來增強基本輸入輸出流的功能。例如,BufferedInputStream和BufferedOutputStream類通過裝飾基本的InputStream和OutputStream來提供緩沖功能。同樣,DataInputStream和DataOutputStream為基本的流添加了讀寫基本數據類型的能力。
Java Servlet API
Java Servlet API中的HttpServletRequestWrapper和HttpServletResponseWrapper類允許開發者通過裝飾原始的HttpServletRequest和HttpServletResponse對象來添加或修改功能。
Java動態代理
Java的動態代理機制允許在運行時創建一個實現了一組接口的代理類實例。這個代理實例實際上是一個裝飾器,它可以在不修改原始對象代碼的情況下,為原始對象添加新的行為,如事務管理、日志記錄等。
Spring框架
Spring框架在很多地方使用了裝飾器模式,例如在AOP(面向切面編程)中,Spring會創建代理對象來包裝目標對象,以實現事務管理、權限檢查等橫切關注點的功能。
Apache Commons IO
Apache Commons IO庫提供了一些裝飾器類,如ProxyInputStream和ProxyOutputStream,這些類可以用來創建自定義的流裝飾器。
JDBC
JDBC驅動程序有時會使用裝飾器模式來增強或修改原始的Connection、Statement或ResultSet對象的行為。
JAX-RS
JAX-RS(Java API for RESTful Web Services)中的客戶端API允許使用裝飾器模式來增強或修改Client、WebTarget、Invocation等對象的行為。

4. Spring 哪些地方用到了裝飾器模式

AOP(面向切面編程):
Spring AOP允許通過聲明式方式添加橫切關注點(如日志記錄、事務管理、安全檢查等)到目標對象。Spring創建代理對象來包裝目標對象,這些代理對象在調用目標方法前后執行額外的代碼。這實際上是一種裝飾器模式的應用,它允許在不修改目標對象代碼的情況下增強其行為。
事務管理
在Spring中,事務管理通常是通過AOP實現的。Spring可以為目標方法創建一個代理,該代理在方法執行前后管理事務的開啟和關閉,而無需修改目標方法的代碼。
Spring Security
Spring Security使用方法攔截器來實現安全控制。它可以為目標方法創建代理,這些代理在方法執行前檢查用戶的權限,如果用戶沒有足夠的權限,則不允許執行目標方法。
Spring Data JPA
Spring Data JPA中的倉庫(Repository)可以通過自定義的實現來擴展。開發者可以創建一個自定義的倉庫實現,并通過Spring的配置將其與標準倉庫接口關聯起來。這實際上是在使用裝飾器模式來擴展倉庫的功能。
Spring WebFlux
Spring WebFlux中的WebFilter和WebExceptionHandler可以被視為裝飾器模式的應用。它們允許在請求處理的各個階段添加額外的處理邏輯,而不需要修改原始的處理器代碼。
Spring Cloud
在Spring Cloud中,裝飾器模式被用于實現服務斷路器、負載均衡等功能。例如,Hystrix斷路器可以通過裝飾原始的服務調用邏輯來添加斷路器功能,從而在服務調用失敗時提供備選方案。
Spring Boot
Spring Boot自動配置的原理也可以看作是裝飾器模式的一種應用。Spring Boot可以自動配置各種組件,如數據源、事務管理器等,這些自動配置的組件可以被用戶的自定義配置所增強或覆蓋。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/22949.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/22949.shtml
英文地址,請注明出處:http://en.pswp.cn/web/22949.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前端面試題日常練-day53 【面試題】

題目 希望這些選擇題能夠幫助您進行前端面試的準備,答案在文末 1. 在PHP中,以下哪個函數可以用于從一個數組的末尾刪除一個元素并返回被刪除的元素? a) array_pop() b) array_push() c) array_shift() d) array_unshift() 2. 在PHP中&…

列存在 OceanBase 數據庫架構中的應用與演進

OceanBase 4.3 版本上線了列存功能,以滿足實時分析的需求。 本文作為《特性解讀:列存技術》的后續,將詳細闡述列存技術在OceanBase數據庫架構中的應用、發展歷程,以及未來的趨勢。 一、前言 1970 年,關系模型之父 Co…

LeakSearch:針對網絡公開憑證的安全掃描與檢測工具

關于LeakSearch 在紅隊演戲過程中,往往需要獲取到針對目標域的訪問權限。在這個過程中,很多紅隊人員會選擇使用暴露在互聯網上的代理服務器來實現目標域的訪問,那么此時就需要在互聯網上收集公開暴露的憑證信息。 對于藍隊來說,…

Playwright+Python+Pytest:基礎方法二次封裝簡化及鏈式調用

引言 隨著Web應用的日益復雜化,自動化測試成為了確保軟件質量的關鍵環節。Playwright 是一個強大的自動化庫,它支持在 Chromium、Firefox 和 WebKit 中運行自動化腳本。本文將介紹如何使用 Playwright 的 Python 同步 API 來簡化點擊和填充操作&#xf…

阿里云郵件推送配置教程:API配置的步驟?

阿里云郵件推送服務如何使用?如何配置郵件推送服務? 阿里云提供了強大的郵件推送服務,幫助企業高效地發送郵件通知、驗證碼、營銷活動等。Aok將詳細介紹阿里云郵件推送的配置教程,以及API配置的步驟,同時簡要提及AokS…

數據流圖要點和難點實際應用

數據流圖(Data Flow Diagram,DFD)是一種圖形化表示信息系統中數據流動和處理的方式。它主要用于描述系統如何接收輸入數據,經過一系列的處理步驟,然后產生輸出數據。數據流圖在系統設計階段特別有用,因為它可以幫助開發人員、業務分析師和其他利益相關者更好地理解系統的…

Python字符串數據類型之字符串

四、Python數據類型 4.1、Python內置數據類型 整型:int浮點型:float布爾類型:bool字符串:str二進制類型:bytes、bytearray復數:complex列表:list元組:tuple字典:dict a…

C#WPF控件Textbox綁定浮點型數據限制小數位方法

本文講解C#WPF控件Textbox綁定浮點型數據限制小數位方法。 XAML中,使用StringFormat來格式化TextBox的文本 <Window x:Class="WpfApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.m…

【使用 uiautomator2 腳本進行波點音樂app自動化操作的教程】

本教程將指導您使用 uiautomator2 庫編寫腳本&#xff0c;實現自動化操作。如果您需要在設備斷開連接或出現異常時重新連接設備并繼續執行任務&#xff0c;這里有一份詳細的代碼示例和使用說明。 環境準備 安裝 Python&#xff1a; 確保您的系統上安裝了 Python&#xff08;推…

[數據集][目標檢測]盲道檢測數據集VOC+YOLO格式2173張1類別

數據集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路徑的txt文件&#xff0c;僅僅包含jpg圖片以及對應的VOC格式xml文件和yolo格式txt文件) 圖片數量(jpg文件個數)&#xff1a;2173 標注數量(xml文件個數)&#xff1a;2173 標注數量(txt文件個數)&#xff1a;2173 標注…

基于R語言BIOMOD2 及機器學習方法的物種分布模擬與案例分析實踐技術

BIOMOD2是一個R軟件包&#xff0c;用于構建和評估物種分布模型&#xff08;SDMs&#xff09;。它集成了多種統計和機器學習方法&#xff0c;如GLM、GAM、SVM等&#xff0c;允許用戶預測和分析物種在不同環境條件下的地理分布。通過這種方式&#xff0c;BIOMOD幫助研究者評估氣候…

常用接口測試及接口抓包常用的測試工具

一、常用抓包工具 01、F12 Web端的話&#xff0c;google瀏覽器直接F12開發者模式 點擊network進行抓包分析。 02、Fiddler抓包工具 客戶端和服務端的http代理&#xff0c;客戶端所有的請求都要先經過Fiddler&#xff0c;到響應的服務端&#xff0c;然后端返回的所有數據也都…

pytorch數學操作

文章目錄 1.torch.bitwise_not()2.torch.bitwise_and()3.torch.ceil()3.torch.clamp()4.torch.torch.floor() 1.torch.bitwise_not() 在 PyTorch 中&#xff0c;torch.bitwise_not() 是一個函數&#xff0c;用于執行逐元素的位非&#xff08;bitwise NOT&#xff09;操作。 t…

如何組織基于Sqlalchemy的項目

在使用 SQLAlchemy 構建項目時&#xff0c;可以遵循一些常用的組織結構和最佳實踐&#xff0c;以確保項目清晰、易于維護。下面就是我在構建項目時遇到的一些問題&#xff0c;并做了詳細的記錄&#xff0c;為了方便大家學習少走一些彎路。 1、問題背景 在基于Sqlalchemy的項目…

IDEA的使用配置Maven(及selenium+webdriver的下載配置)

一. 下載maven 1. maven官網下載鏈接 2.??安裝第二行第一列的zip壓縮包 ???????? 二. 配置環境變量 1.新建環境變量 2.在系統變量Path環境變量中添加%Maven_HOME%\bin 三.驗證環境變量是否配置成功 winr >cmd>mvn -v 如果出現Maven的版本信息&#xff0…

Matlab解決矩陣微分方程建模(代碼開源)

#用matlab解決施密特正交規范化矩陣之后&#xff0c;我又想到矩陣的微分方程計算量真的太大了&#xff0c;來回轉化讓我頭大&#xff0c;于是我嘗試了一下用matlab建立模型來解決這類問題。 代碼部分如下&#xff1a;注解還挺清晰的&#xff1a; %%%解微分方程組%eg&#xff…

【設計模式】代理模式(結構型)???

文章目錄 1.概念1.1 什么是代理模式1.2 優點與缺點 2.實現方式2.1 靜態代理2.2 動態代理 3. Java 哪些地方用到了代理模式4. Spring 哪些地方用到了代理模式 1.概念 1.1 什么是代理模式 代理模式&#xff08;Proxy Pattern&#xff09;是一種結構型設計模式&#xff0c;它允許…

帶你認識ffmpeg

FFmpeg是一個開源的跨平臺音視頻處理工具集&#xff0c;它提供了豐富的音視頻處理功能和庫&#xff0c;被廣泛應用于音視頻編解碼、格式轉換、流媒體處理等領域。 應用場景&#xff1a; 視頻編解碼&#xff1a;FFmpeg可以對各種視頻格式進行編解碼&#xff0c;包括但不限于AV…

類的特殊成員函數

使用類的嵌套&#xff0c;并自定義析構函數 #include <iostream>using namespace std; class Per{ private:string name;int age;double hight;double weight; public:Per(string name,int age,double hight,double weight):name(name),age(age),hight(hight),weight(we…

圖片如何修改尺寸?四種好用的修改圖片尺寸方法!

圖片如何修改尺寸&#xff1f;圖片是一種常見的文件類型&#xff0c;它存在于什么生活的方方面面&#xff0c;雖然圖片很好用&#xff0c;但是大家日常也要注意圖片的尺寸&#xff0c;如果圖片尺寸不對是會帶來很多問題的&#xff0c;下面小編就舉例說明幾個問題&#xff0c;首…