《設計模式之禪》筆記摘錄 - 10.裝飾模式

裝飾模式的定義

裝飾模式(Decorator Pattern)是一種比較常見的模式,其定義如下:

Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.(動態地給一個對象添加一些額外的職責。就增加功能來說,裝飾模式相比生成子類更為靈活。)

在類圖中,有四個角色需要說明:

Component抽象構件。Component是一個接口或者是抽象類,就是定義我們最核心的對象,也就是最原始的對象。裝飾模式中,必然有一個最基本、最核心、最原始的接口或抽象類充當Component抽構件。

ConcreteComponent具體構件。ConcreteComponent是最核心、最原始、最基本的接口或抽象類的實現,你要裝飾的就是它。

Decorator裝飾角色一般是一個抽象類,做什么用呢?實現接口或者抽象方法,它里面可不一定有抽象的方法呀,在它的屬性里必然有一個private變量指向Component抽象構件。

具體裝飾角色ConcreteDecoratorA和ConcreteDecoratorB是兩個具體的裝飾類,你要把你最核心的、最原始的、最基本的東西裝飾成其他東西。

裝飾模式應用

裝飾模式的優點

裝飾類和被裝飾類可以獨立發展,而不會相互耦合。換句話說,Component類無須知道Decorator類,Decorator類是從外部來擴展Component類的功能,而Decorator也不用知道具體的構件。

裝飾模式是繼承關系的一個替代方案。我們看裝飾類Decorator,不管裝飾多少層,返回的對象還是Component,實現的還是is-a的關系。裝飾模式可以動態地擴展一個實現類的功能,這不需要多說,裝飾模式的定義就是如此。

裝飾模式的缺點

對于裝飾模式記住一點就足夠了:多層的裝飾是比較復雜的。為什么會復雜呢?你想想看,就像剝洋蔥一樣,你剝到了最后才發現是最里層的裝飾出現了問題,想象一下工作量吧,因此,盡量減少裝飾類的數量,以便降低系統的復雜度。

裝飾模式的使用場景

要擴展一個類的功能,或給一個類增加附加功能。需要動態地給一個對象增加功能,這些功能可以再動態地撤銷。需要為一批的兄弟類進行改裝或加裝功能,當然是首選裝飾模式。

最佳實踐

裝飾模式是對繼承的有力補充。你要知道繼承不是萬能的,繼承可以解決實際的問題,但是在項目中你要考慮諸如易維護、易擴展、易復用等,而且在一些情況下你要是用繼承就會增加很多子類,而且靈活性非常差,那當然維護也不容易了,也就是說裝飾模式可以替代繼承,解決我們類膨脹的問題。

同時,你還要知道繼承是靜態地給類增加功能,而裝飾模式則是動態地增加功能,如果你用繼承就必須修改程序。

裝飾模式還有一個非常好的優點:擴展性非常好。在一個項目中,你會有非常多的因素考慮不到,特別是業務的變更,不時地冒出一個需求,尤其是提出一個令項目大量延遲的需求時,那種心情是相當的難受!裝飾模式可以給我們很好的幫助,通過裝飾模式重新封裝一個類,而不是通過繼承來完成,簡單點說,三個繼承關系Father, Son, GrandSon三個類,我要在Son類上增強一些功能怎么辦?我想你會堅決地頂回去!不允許,對了,為什么呢?你增強的功能是修改Son類中的方法嗎?增加方法嗎?對GrandSon的影響呢?特別是GrandSon有多個的情況,你會怎么辦?這個評估的工作量就夠你受的,所以這是不允許的,那還是要解決問題的呀,怎么辦?通過建立SonDecorator類來修飾Son,相當于創建了一個新的類,這個對原有程序沒有變更,通過擴展很好地完成了這次變更。

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

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

相關文章

[AI8051U入門第十步]W5500-客戶端

學習目標: 1、認識W5500模塊 2、驅動W5500靜態獲取ip 3、獲取全球唯一碼作為mac地址 4、拔出網線重插網線自動獲取IP 5、編寫W5500作為客戶端進行TCP/IP代碼一、W5500介紹 W5500 是一款由韓國 WIZnet 公司推出的高性能 硬件 TCP/IP 嵌入式以太網控制器,專為嵌入式系統設計,…

UNETR++: Delving Into Efficient and Accurate 3D Medical Image Segmentation

摘要得益于Transformer模型的成功,近期研究開始探索其在3D醫學分割任務中的適用性。在Transformer模型中,自注意力機制是核心構建模塊之一,與基于局部卷積的設計相比,它致力于捕捉長距離依賴關系。然而,自注意力操作存…

Kotlin Flow 在 Jetpack Compose 中的正確打開方式:SharedFlow vs StateFlow 與 LaunchedEffect

在 Jetpack Compose 中,Kotlin Flow 是處理異步數據流的核心工具,而 SharedFlow 和 StateFlow 是最常用的兩種 Flow 類型。但很多開發者對它們的適用場景、如何與 LaunchedEffect 配合使用存在困惑。本文將深入探討它們的區別,并給出最佳實踐…

嵌入式——C語言:指針①

一、指針特點1.讓代碼更加簡潔高效2.提供直接訪問內存的操作3.利用指針可以直接操作硬件二、指針概念(一)地址:為了區分內存中不同字節的編號(0到2^16-1)(二)指針:指針就是地址&…

RabbitMQ—HAProxy負載均衡

上篇文章: RabbitMQ—仲裁隊列https://blog.csdn.net/sniper_fandc/article/details/149312579?fromshareblogdetail&sharetypeblogdetail&sharerId149312579&sharereferPC&sharesourcesniper_fandc&sharefromfrom_link 目錄 1 HAProxy安裝…

QT中啟用VIM后粘貼復制快捷鍵失效

當在QT中啟用FakeVim之后,Ctrl C 和 Ctrl V 快捷鍵就變成 Vim 的快捷鍵了,我希望它還是原來的復制粘貼功能,打開:編輯 > Preferences…,然后勾選 “Pass control keys”即可,如下:

TCP三次握手與四次揮手全解析

🌊 TCP三次握手與四次揮手全解析(含序列號動態追蹤)🔑 TCP 協議核心機制 序列號 (seq):數據字節流的唯一標識(32位循環計數器)確認號 (ack):期望接收的下一個序列號(ack …

7月26號打卡

作業:題目1:計算圓的面積 任務: 編寫一個名為 calculate_circle_area 的函數,該函數接收圓的半徑 radius 作為參數,并返回圓的面積。圓的面積 π * radius (可以使用 math.pi 作為 π 的值)要求:函數接收一…

C++/CLI與標準C++的語法差異(一)

🌌 C/CLI與標準C的語法差異(一)🔬 第一章:類型系統革命 - 徹底解構三語言范式 🧪 1.1 類型聲明語義差異矩陣 #mermaid-svg-L5kQ3iy05pKo4vIj {font-family:"trebuchet ms",verdana,arial,sans-se…

輸電線路微氣象在線監測裝置:保障電網安全的科技屏障

在電力傳輸網絡中,輸電線路微氣象在線監測裝置通過集成專業傳感器與智能分析技術,實現對線路周邊環境參數的實時采集與動態分析,為電網運行安全提供數據支撐。該設備針對輸電線路特殊工況設計,具備高適應性、高可靠性特點。工作原…

基于springboot的圖書借閱系統

用戶:借閱信息管理,續借信息管理,還書信息管理,圖書信息,系統公告,留言板,我的中心管理員:圖書信息管理,圖書類型管理,借閱信息管理,續借信息管理…

Xinference vs SGLang:詳細對比分析

概述對比特性XinferenceSGLang定位通用AI模型推理平臺高性能LLM服務框架專注領域多模態模型統一接口LLM推理性能優化設計理念易用性和兼容性性能和效率核心架構對比 Xinference 架構特點 Xinference 架構: ├── API層(REST/CLI/Python) ├─…

雙非上岸985!專業課140分經驗!信號與系統考研專業課140+上岸中南大學,通信考研小馬哥

一.經驗分享個人情況:初試總分377,政治59,英語二75、數學二103、專業課140。本科為湖南一所雙非一本,專業是電子信息工程,本科成績一般,無獎學金無評優無科研競賽,屬于三無人員&…

配置DNS正反向解析

服務端master配置:yum install bind -y配置靜態ip:修改配置文件:主:區域:正向解析:反向解析:開啟服務:客戶端node1配置:yum install nginx -y配置靜態ip:使用xftp將文…

MyBatis-Plus 通用 Service

引言 在開發 Java Web 應用程序時,我們經常需要進行大量的數據庫操作,如創建、讀取、更新和刪除(CRUD)。MyBatis-Plus 作為一個強大的 MyBatis 增強工具,為我們提供了通用 Service 接口,極大地簡化了這些操…

聚類-一種無監督分類算法

目錄 1、聚類任務 2、性能度量 (1)外部指標 (2)內部指標 3、具體聚類方法 (1)原型聚類 (2)密度聚類 (3)層次聚類 “無監督學習”(unsupervised learnin…

ES6 標簽模板:前端框架的靈活利器

ES6(ECMAScript 2015)引入的模板字符串(Template Literals)為 JavaScript 開發者提供了更簡潔的字符串處理方式,而模板字符串標簽(Tagged Template Literals)則進一步擴展了其功能性。通過標簽函…

解鎖編程核心能力:深入淺出數據結構和算法

——為什么它們是你代碼效率的終極武器? 🌟 引言:程序世界的基石 想象你正在建造摩天大樓:數據結構是鋼筋骨架,決定建筑的結構與承重能力;算法則是施工藍圖,指導如何高效完成建造。兩者結合&am…

Jenkins運行pytest時指令失效的原因以及解決辦法

錯誤收集 Started by user 偷走晚霞的人 Running as SYSTEM Building in workspace C:\Users\Administrator\.jenkins\workspace\TestAAA [TestAAA] $ cmd /c call C:\Users\Administrator\AppData\Local\Temp\jenkins5821160869728612887.bat C:\Users\Administrator\.jenkins…

MySQL數據庫本地遷移到云端完整教程

一、準備工作 安裝MySQL客戶端工具獲取云端數據庫連接信息: 主機地址端口號用戶名密碼數據庫名二、本地數據庫導出 mysqldump -h 127.0.0.1 -P 4406 -u root -p 數據庫名 > backup.sql執行后會提示輸入密碼,完成后會在當前目錄生成backup.sql文件 三、…