裝飾器設計模式是什么?什么是 Decorator 裝飾器設計模式?Python 裝飾器設計模式示例代碼

什么是 Decorator 裝飾器設計模式?

裝飾器模式是一種結構型設計模式,它允許向現有對象動態地添加新功能,同時不改變其結構。這種模式實現了對對象的包裝,稱為裝飾器,并且可以在運行時動態地添加、修改或刪除對象的行為。

在這里插入圖片描述

主要思想:

裝飾器模式允許你通過將對象放入包含行為的特殊包裝器對象中來為原始對象添加新功能,使得代碼更靈活、可重用,并且遵循開放-封閉原則。

主要角色:

  1. Component(組件): 定義了一個對象接口,可以動態地為該對象添加職責。
  2. ConcreteComponent(具體組件): 實現了 Component 接口的具體對象,是被裝飾的原始對象。
  3. Decorator(裝飾器): 持有一個指向 Component 對象的引用,并定義一個與 Component 接口一致的接口。
  4. ConcreteDecorator(具體裝飾器): 向組件添加新的功能。

在這里插入圖片描述

工作流程:

  1. 創建一個 Component 接口以及其具體實現 ConcreteComponent。
  2. 創建一個裝飾器類,實現與 Component 相同的接口,并持有一個 Component 對象作為其成員變量。
  3. 創建具體裝飾器類,對裝飾器類進行擴展,添加額外的功能。

優點:

  1. 靈活性和擴展性: 可以動態地向對象添加新的功能,而無需修改其結構。可以通過堆疊裝飾器來組合不同的功能,實現更多的組合方式。

  2. 遵循開放-封閉原則: 可以在不修改現有代碼的情況下,通過裝飾器來擴展功能,遵循了開放-封閉原則,使得系統更易于擴展。

  3. 單一職責原則: 可以將不同的責任分配給不同的裝飾器,使得每個裝飾器只關注一個特定的功能,符合單一職責原則。

  4. 代碼復用性: 裝飾器可以被多個對象共享使用,提高了代碼的復用性,避免了重復編寫相似功能的代碼。

缺點:

  1. 復雜性增加: 可能會導致類層次結構變得復雜,堆疊過多的裝飾器可能會使代碼難以理解和維護。

  2. 運行時影響: 在運行時動態地添加功能,可能會影響系統的性能,特別是堆疊過多的裝飾器可能會增加函數調用的開銷。

  3. 正確性和順序: 裝飾器的正確性和順序是很重要的,裝飾器的堆疊順序可能會影響最終的結果,需要小心處理。

  4. 不適用所有情況: 裝飾器并不適用于所有情況。有些情況可能會使用其他設計模式更為合適,需要根據具體情況進行選擇。

總的來說,裝飾器模式提供了一種靈活的方式來擴展對象的功能,但需要權衡其增加的復雜性和運行時的影響。在適當的情況下使用,能夠有效地提高代碼的可擴展性和可維護性。


Python 實現裝飾器設計模式示例代碼(一):

# Component 接口
class Coffee:def cost(self):pass# ConcreteComponent
class SimpleCoffee(Coffee):def cost(self):return 5# Decorator 裝飾器類
class CoffeeDecorator(Coffee):def __init__(self, coffee):self._coffee = coffeedef cost(self):return self._coffee.cost()# ConcreteDecorator 具體裝飾器類
class Milk(CoffeeDecorator):def cost(self):return self._coffee.cost() + 2class Sugar(CoffeeDecorator):def cost(self):return self._coffee.cost() + 1# 使用示例
coffee = SimpleCoffee()
print(coffee.cost())  # 輸出:5coffee_with_milk = Milk(coffee)
print(coffee_with_milk.cost())  # 輸出:7coffee_with_milk_and_sugar = Sugar(coffee_with_milk)
print(coffee_with_milk_and_sugar.cost())  # 輸出:8

在這個示例中,Coffee 是組件接口,SimpleCoffee 是具體組件,CoffeeDecorator 是裝飾器類,MilkSugar 是具體裝飾器類。通過裝飾器模式,可以動態地為咖啡對象添加不同的裝飾(牛奶、糖),每個裝飾器都可以增加價格。


Python 實現裝飾器設計模式示例代碼(二):

當處理網頁生成時,可以使用裝飾器模式來動態地添加不同的 HTML 樣式和元素。

# Component 接口
class HTMLPage:def show(self):pass# ConcreteComponent
class BasicHTMLPage(HTMLPage):def show(self):return "Basic HTML Page"# Decorator 裝飾器類
class HTMLDecorator(HTMLPage):def __init__(self, html_page):self._html_page = html_pagedef show(self):return self._html_page.show()# ConcreteDecorator 具體裝飾器類
class BoldDecorator(HTMLDecorator):def show(self):return f"<b>{self._html_page.show()}</b>"class ItalicDecorator(HTMLDecorator):def show(self):return f"<i>{self._html_page.show()}</i>"# 使用示例
basic_page = BasicHTMLPage()
print(basic_page.show())  # 輸出:Basic HTML Pagebold_page = BoldDecorator(basic_page)
print(bold_page.show())  # 輸出:<b>Basic HTML Page</b>italic_bold_page = ItalicDecorator(bold_page)
print(italic_bold_page.show())  # 輸出:<i><b>Basic HTML Page</b></i>

在這個示例中,HTMLPage 是組件接口,BasicHTMLPage 是具體組件,HTMLDecorator 是裝飾器類,BoldDecoratorItalicDecorator 是具體裝飾器類。通過裝飾器模式,可以動態地為基本 HTML 頁面添加不同的樣式,比如加粗、斜體等。


使用裝飾器設計模式時,需要注意哪些地方?

在使用裝飾器設計模式時,需要留意以下幾個方面:

  1. 繼承關系: 裝飾器模式通過繼承實現,這可能導致類層次結構變得復雜。過多的裝飾器可能會使代碼難以理解和維護。

  2. 功能堆疊順序: 裝飾器的堆疊順序很重要,可能會影響最終結果。確保裝飾器按照正確的順序應用,避免意外的行為。

  3. 適用性和靈活性: 裝飾器模式并不適用于所有情況。在某些情況下,可能會使用其他模式更為合適,需要根據具體情況進行選擇。

  4. 影響性能: 堆疊過多的裝飾器可能會影響性能,特別是在對性能敏感的場景下。過多的裝飾器會增加函數調用的開銷。

  5. 單一職責原則: 確保每個裝飾器只關注一個特定的功能。不要讓裝飾器變得過于復雜,應遵循單一職責原則。

  6. 可讀性和維護性: 過多的裝飾器可能會降低代碼的可讀性和維護性。建議在使用裝飾器時保持代碼簡潔易懂。

  7. Python 特殊性: 在 Python 中,裝飾器是一種語法糖,經常用于修飾函數。但使用裝飾器時要注意其影響范圍和作用域。

總的來說,裝飾器模式是一種靈活且強大的模式,但需要謹慎使用,特別是在需要管理復雜裝飾器堆疊和性能敏感的情況下。


本文就到這里了,感謝您的閱讀 。別忘了點贊、收藏~ Thanks?(・ω・)ノ 🍇

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

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

相關文章

重磅!這本30w人都在看的Python數據分析暢銷書:更新了!

想學習python進行數據分析&#xff0c;這本《利用python進行數據分析》是繞不開的一本書。目前該書根據Python3.10已經更新到第三版。 Python 語言極具吸引力。自從 1991 年誕生以來&#xff0c;Python 如今已經成為最受歡迎的解釋型編程語言。 pandas 誕生于2008年。它是由韋…

NX二次開發UF_CAM_set_clear_plane_data 函數介紹

文章作者&#xff1a;里海 來源網站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_set_clear_plane_data Defined in: uf_cam_planes.h int UF_CAM_set_clear_plane_data(tag_t object_tag, double origin [ 3 ] , double normal [ 3 ] ) overview 概述 De…

快慢指針判斷環形鏈表

我們在前面文章中寫過用快慢指針判斷鏈表是否帶環&#xff1a; leetcode&#xff1a;環形鏈表-CSDN博客 我們用的是slow指針一次走一步&#xff0c;fast指針一次走兩步&#xff0c;當slow入環后開始了追擊&#xff0c;每走一次距離縮短1&#xff0c;最終就會相遇 思考問題 …

【LeetCode】每日一題 2023_11_23 HTML 實體解析器(調庫/打工)

文章目錄 刷題前嘮嗑題目&#xff1a;HTML 實體解析器題目描述代碼與解題思路 結語 刷題前嘮嗑 題目&#xff1a;HTML 實體解析器 題目鏈接&#xff1a;1410. HTML 實體解析器 題目描述 代碼與解題思路 func entityParser(s string) (ans string) {return strings.NewRepla…

redo log 丟失或者損壞-ORA-01194: 文件 1 需要更多的恢復來保持一致性

#故障場景描述&#xff1a; 1、current redo 損壞或者丟失 2、ORA-01194: 文件 1 需要更多的恢復來保持一致性 C:\Users\ZMI>sqlplus / as sysdba SQL*Plus: Release 19.0.0.0.0 - Production on 星期三 11月 22 16:58:07 2023 Version 19.3.0.0.0 Copyright (c) 1982, …

NX二次開發UF_CAM_set_lower_limit_plane_tag 函數介紹

文章作者&#xff1a;里海 來源網站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_set_lower_limit_plane_tag Defined in: uf_cam_planes.h int UF_CAM_set_lower_limit_plane_tag(tag_t object_tag, tag_t target_tag ) overview 概述 Set the tag of a …

使用 PowerShell 創建共享目錄

在 Windows 中&#xff0c;可以使用共享目錄來將文件和文件夾共享給其他用戶或計算機。共享目錄可以通過網絡訪問&#xff0c;這使得它們非常適合用于文件共享、協作和遠程訪問。 要使用 PowerShell 創建共享目錄&#xff0c;可以使用 New-SmbShare cmdlet。New-SmbShare cmdl…

TypeScript 項目 Airbnb 語法風格 ESLint 配置

TypeScript 項目 Airbnb 語法風格 ESLint 配置 1. 配置 安裝&#xff1a; npm i -D eslint-config-airbnb-typescript typescript-eslint/eslint-plugin^6.0.0 typescript-eslint/parser^6.0.0配置&#xff1a; .eslintrc.js: module.exports {root: true,env: {node: true…

【Antd】antd的Form表單項用Form.Item包裹后,表單校驗不生效的原因及解決辦法

以下代碼是用<Form></Form>包裹的子組件中的render部分的代碼&#xff1a; 可以看到Input.TextArea被<div>包裹住了&#xff0c;這會導致無法被Form表單識別并抓取&#xff0c;因為Form默認只允許放一個子元素。 <div className{styles.textAreaWrap}&g…

算法的奧秘:常見的六種算法(算法導論筆記2)

算法的奧秘&#xff1a;種類、特性及應用詳解&#xff08;算法導論筆記1&#xff09; 上期總結算法的種類和大致介紹&#xff0c;這一期主要講常見的六種算法詳解以及演示。 排序算法&#xff1a; 排序算法是一類用于對一組數據元素進行排序的算法。根據不同的排序方式和時間復…

postman定義公共函數這樣寫,測試組長直呼牛逼!!!

postman定義公共函數 在postman中&#xff0c;如下面的代碼&#xff1a; 1、返回元素是否與預期值一致 var assertEqual(name,actual,expected)>{tests[${name}&#xff1a;實際結果&#xff1a; ${actual} &#xff0c; 期望結果&#xff1a;${expected}]actualexpected…

2023年危險化學品經營單位主要負責人證模擬考試題庫及危險化學品經營單位主要負責人理論考試試題

題庫來源&#xff1a;安全生產模擬考試一點通公眾號小程序 2023年危險化學品經營單位主要負責人證模擬考試題庫及危險化學品經營單位主要負責人理論考試試題是由安全生產模擬考試一點通提供&#xff0c;危險化學品經營單位主要負責人證模擬考試題庫是根據危險化學品經營單位主…

Exception:Zero date value prohibited

運行了很久的系統&#xff0c;突然不能訪問&#xff0c;報錯如下&#xff1a; Error attempting to get column updated_time from result set. Cause: java.sql.SQLException: Zero date value prohibited; SQL []; Zero date value prohibited; nested exception is java.…

【追求卓越12】算法--堆排序

引導 前面幾節&#xff0c;我們介紹了有關樹的數據結構&#xff0c;我們繼續來介紹一種樹結構——堆。堆的應用場景有很多&#xff0c;比如從大量數據中找出top n的數據&#xff1b;根據優先級處理網絡請求&#xff1b;這些情景都可以使用堆數據結構來實現。 什么是堆&#xf…

【20年揚大真題】編寫程序,功能是計算1~10之間的偶數之和

【20年揚大真題】 編寫程序&#xff0c;功能是計算1~10之間的偶數之和 #include<stdio.h> int main() {int i 1;int sum 0;for (i 1;i < 10;i){if (i % 2 0){sum i;}}printf("%d", sum); }

Java核心知識點整理大全9-筆記

目錄 null文章瀏覽閱讀9w次&#xff0c;點贊7次&#xff0c;收藏7次。Java核心知識點整理大全https://blog.csdn.net/lzy302810/article/details/132202699?spm1001.2014.3001.5501 Java核心知識點整理大全2-筆記_希斯奎的博客-CSDN博客 Java核心知識點整理大全3-筆記_希斯…

FindMy技術用于充電寶

充電寶是一種便捷的充電器&#xff0c;方便個人隨身攜帶&#xff0c;能夠自行儲備電能&#xff0c;為主流電子設備提供充電服務。它廣泛應用于沒有外部電源供應的場所&#xff0c;例如旅行、戶外活動或緊急情況下&#xff0c;為用戶的手持設備提供持續的電力支持&#xff0c;確…

spring boot加mybatis puls實現,在新增/修改時,對某些字段進行處理,使用的@TableField()或者AOP @Before

1.先說場景&#xff0c;在對mysql數據庫表數據插入或者更新時都得記錄時間和用戶id 傳統實現有點繁瑣&#xff0c;這里還可以封裝一下公共方法。 2.解決方法&#xff1a; 2.1&#xff1a;使用aop切面編程&#xff08;記錄一下&#xff0c;有時間再攻克&#xff09;。 2.1.1&am…

讀書筆記:彼得·德魯克《認識管理》第30章 管理溝通

一、章節內容概述 我們知道&#xff0c;組織中的溝通是感知&#xff0c;也是期望&#xff0c;會產生要求&#xff0c;并且與信息不同&#xff0c;二者是對立的卻相互依賴。 我們知道&#xff0c;下行溝通沒有效果&#xff0c;只有上行溝通才能達到目的&#xff0c;并且 我們還…

軟件工程第十二周

軟件作坊、軟件危機、軟件過程控制、重型控制、敏捷、DevOps 這些術語概括了軟件開發歷史和實踐中的幾個重要概念和階段。讓我們逐一解析它們&#xff1a; 軟件作坊&#xff08;Software Craftsmanship&#xff09;&#xff1a;這是軟件開發的早期模式&#xff0c;強調個人技能…