Python设计模式 - 装饰模式

定义

装饰模式(Decorator Pattern)是一种结构型设计模式,用于在不修改原有类的情况下动态地扩展对象的功能。

结构

在这里插入图片描述

  • 抽象组件(Component):定义对象的公共接口,使得客户端能以一致的方式处理未被装饰的对象和装饰之后的对象。
  • 具体组件(Concrete Component):实现抽象组件接口,是被装饰的对象。
  • 装饰器(Decorator):实现抽象组件接口,并持有一个抽象组件的引用(即被装饰的对象)。
  • 具体装饰器(Concrete Decorator):扩展组件对象的行为。

应用场景

  1. 不修改原有类代码的情况下扩展其功能:当原有类已经投入使用,或者由于某些原因(如第三方库)无法直接修改时,可以使用装饰模式来扩展功能,而不影响原有类的结构。例如,日志系统中对原始日志进行加密、压缩、写入多个目标(如控制台、文件、远程服务器)等。
  2. 替代复杂的继承结构:当功能组合的可能性较多,使用继承会导致子类爆炸时,装饰模式是一种更好的解决方案。相比于继承,它提供了更高的灵活性,可以在运行时自由组合功能,而不是提前在类层次结构中定义。例如,图形渲染系统中对图形添加不同的修饰(阴影、边框、透明度调整)等。

优缺点

优点

  1. 比继承更灵活,避免类爆炸:继承方式扩展功能时,每个新的功能组合都可能导致大量的子类。而装饰模式可以通过对象组合动态扩展,不需要为每种组合定义一个新的子类。
  2. 提高代码的可复用性:每个装饰器都是独立的,可以在不同的对象上复用,避免了在每个类中实现类似功能的重复工作。
  3. 装饰器可以叠加,提供更强的扩展能力:由于装饰器遵循相同的接口,可以通过嵌套多个装饰器来灵活组合功能,从而轻松实现复杂的功能增强。

缺点

  1. 增加了系统的复杂性:装饰模式通过组合多个小的装饰器来扩展功能,可能导致系统中产生大量的装饰器对象,特别是在功能组合较多时,增加了理解和维护的难度。
  2. 可能影响性能:每次方法调用都需要经过多个装饰器的转发和处理,尤其是装饰器链较长时,这可能导致性能下降,尤其在高频调用的场景下更加明显。
  3. 可能导致调试困难:装饰器层层嵌套,每个装饰器都可能改变对象的行为,这使得追踪和调试变得更加复杂。

代码示例

from abc import ABC, abstractmethod# 抽象组件类(Component)
class Text(ABC):@abstractmethoddef render(self):pass# 具体组件类(Concrete Component)
class PlainText(Text):def __init__(self, content):self.content = contentdef render(self):return self.content# 装饰器基类(Decorator)
class TextDecorator(Text):def __init__(self, wrapped_text):self._wrapped_text = wrapped_textdef render(self):return self._wrapped_text.render()# 具体装饰器类(Concrete Decorator)- 加粗
class BoldText(TextDecorator):def render(self):return f"<b>{super().render()}</b>"# 具体装饰器类(Concrete Decorator)- 斜体
class ItalicText(TextDecorator):def render(self):return f"<i>{super().render()}</i>"# 具体装饰器类(Concrete Decorator)- 下划线
class UnderlineText(TextDecorator):def render(self):return f"<u>{super().render()}</u>"# 使用装饰模式
if __name__ == "__main__":# 创建原始文本对象text = PlainText("Hello, World!")print(text.render())  # 输出:Hello, World!# 加粗文本bold_text = BoldText(text)print(bold_text.render())  # 输出:<b>Hello, World!</b># 斜体加粗文本italic_bold_text = ItalicText(bold_text)print(italic_bold_text.render())  # 输出:<i><b>Hello, World!</b></i># 斜体加粗下划线文本styled_text = UnderlineText(italic_bold_text)print(styled_text.render())  # 输出:<u><i><b>Hello, World!</b></i></u>

参考

《设计模式的艺术》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/918300.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/918300.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL(188)如何使用MySQL的慢查询工具?

使用MySQL的慢查询工具可以帮助开发者识别和优化性能不佳的SQL查询。以下是详细深入的步骤和代码示例&#xff0c;帮助你使用MySQL的慢查询工具来进行查询分析和优化。 一、启用慢查询日志 首先&#xff0c;你需要确保MySQL的慢查询日志功能是启用的。慢查询日志记录了所有执行…

如何培养自己工程化的能力(python项目)

培养 Python 项目的工程化能力需要系统性训练&#xff0c;以下从基础到高阶的实践路径&#xff0c;结合具体案例和工具链&#xff0c;帮助你逐步进阶&#xff1a;一、夯实工程化基础能力​1. 规范代码与项目结构•​项目模板化​使用 cookiecutter生成标准项目结构&#xff0c;…

AI编程插件对比分析:CodeRider、GitHub Copilot及其他

AI编程插件对比分析:CodeRider、GitHub Copilot及其他 随着人工智能技术的快速发展,AI编程插件已成为提升开发者生产力的重要工具。CodeRider和GitHub Copilot作为市场上的领先者,分别以其独特的特性和生态系统吸引了大量开发者。本文将从功能特性、性能表现、集成性、用户…

uniapp/uniappx实现图片或视频文件选择时同步告知权限申请目的解决华为等应用市场上架审核问题

在UNIAPP支持vue和nvue,在UNIAPPX支持uvue&#xff0c;安卓支持在选择图片或视频文件权限申请的时候自动同步告知权限申请目的。轻松解决在华为应用市场审核&#xff0c;要求告知权限申请目的或说明的问题。 UNIAPP相册图片视频选择器(安卓可以自定义界面样式)功能介绍&#x…

jupyter notebook如何打开其他盘目录

问题描述Jupyter Notebook 相信是我们学习 Python 避不开的一个工具。当我们使用 pip install notebook 安装 Notebook 之后&#xff0c;使用命令 jupyter notebook 启动服务&#xff0c;启动之后默认会在浏览器打开界面。我们会发现&#xff0c;这个界面默认在 C 盘下&#xf…

C语言深度剖析

一、关键字 1.1 最快的关键字-register register 这个关键字请求编译器尽可能将变量存在CPU内部寄存器中,而不是通过内存寻址以提高效率。 注意是:尽可能、而不是绝对 1.1.1 皇帝身边的小太监-寄存器 不知道什么是寄存器,那见过太监没有其实寄存器就是相当于。一个cpu的…

电脑使用“碎片整理”程序的作用

1.解决文件碎片化问题碎片整理的作用&#xff1a;将这些分散的文件片段重新整理、拼接&#xff0c;使其连续存储在硬盘的某个区域&#xff0c;减少文件的 “碎片化” 程度。2. 提升硬盘读写速度机械硬盘的特殊性&#xff1a;机械硬盘依赖磁头的物理移动来读取数据&#xff0c;若…

AI 软件工程开发 AI 算法 架构与业务

AI 软件工程开发 & AI 算法 & 架构与业务前言1.AI 软件工程开发1.1. AI Developer Studio &#xff08;playground级&#xff09;1.2. Agent & RAG1.3. LangChain & LangGraph1.4. MCP, Model Context Protocol1.5. Ollama1.6. Coze & Dify2.AI 算法2.1. G…

uniapp实现的圆形滚盘组件模板

采用 uniapp 实现的一款圆形滚盘示例组件模板, 支持 vue2、vue3&#xff0c;适配H5、微信小程序&#xff08;其他小程序未试过&#xff0c;可自行尝试&#xff09; 代码实现简约易懂&#xff0c;用户可根据自身需求下载模板&#xff0c;并进行扩展开发可到插件市场下载尝试&…

无须炮解,打开即是Pro版

聊一聊 文档或文件转图片&#xff0c;这个我有段时间没有推荐了。 今天发现了一款非常好用的图像格式转换编辑软件。 有需要的小伙伴请及时收藏&#xff0c;防止下次找不到。 软件介绍 全能图像格式转换工具 这是一款全能的图像转换软件&#xff0c;支持几乎所有的图像格式…

企业高性能web服务器——Nginx

Nginx介绍 Nginx是一个高性能的HTTP和反向代理服务器&#xff0c;也是一个邮件代理服务器。由俄罗斯的程序设计师Igor Sysoev所开发&#xff0c;官方测试nginx能够支撑5万并发链接&#xff0c;并且cpu、内存等资源消耗却非常低&#xff0c;运行非常稳定。所以其特点是占有内存…

MCU控制ADAU1701,用System Workbench for STM32导入工程

作者的话 MCU控制ADAU1701&#xff0c;我有写一个文档详细讲步骤&#xff0c;里头用到了System Workbench for STM32这个软件&#xff0c;他是基于eclips内核的开发软件&#xff0c;一般来讲&#xff0c;设置好workspce工程就会出来&#xff0c;但是架不住就有设置好工程不出来…

SQL176 每个题目和每份试卷被作答的人数和次数

描述现有试卷作答记录表exam_record&#xff08;uid用户ID, exam_id试卷ID, start_time开始作答时间, submit_time交卷时间, score得分&#xff09;&#xff1a;iduidexam_idstart_timesubmit_timescore1100190012021-09-01 09:01:012021-09-01 09:41:01812100290022021-09-01 …

构建第三方软件仓库

1 下载第三方软件到指定目录[rootServer_b ~]# mkdir software [rootServer_b software]# wget https://dldir1v6.qq.com/qqfile/qq/QQNT/Linux/QQ_3.2.18_250724_x86_64_01.rpm2 安装软件信息采集工具[rootServer_b software]# yum install createrepo -y [rootServer_b softw…

Linux 管道命令及相关命令练习与 Shell 编程、Tomcat 安装

2.实验目的掌握 Linux 管道命令及相关命令&#xff08;cut、sort、wc、uniq、tee、tr、split&#xff09;的使用方法。学会使用 Shell 编程实现基本的计算器功能。掌握在 CentOS 7 系统中安装 Tomcat 的方法。实验内容1. Linux 管道命令及相关命令练习1.1 管道命令定义&#xf…

蓝牙基础:FIFO(First-In-First-Out)缓存区

在蓝牙通信中&#xff0c;FIFO&#xff08;First-In-First-Out&#xff0c;先进先出&#xff09;缓存区是解决数据传输中“速度不匹配”和“时序异步”问题的核心机制&#xff0c;广泛应用于蓝牙芯片内部、协议栈各层级及主从设备交互中。其核心作用是临时存储数据&#xff0c;…

国内外主流源代码平台与高效开发指南

摘要 本文旨在为您提供一份实用的源代码获取与开发指南。我们将首先梳理国内外最主流的源代码托管平台&#xff0c;并重点介绍如何利用这些平台上的开源项目。接着&#xff0c;本文将为您规划一条针对初学者的“最快最性价比”的开发路径&#xff0c;从环境配置、项目管理到实…

任务进度状态同步 万能版 参考 工厂+策略+观察者设计模式 +锁设计 springboot+redission

文章目录概要效果解释状态流转说明设计AI任务实体类AI任务状态枚举AI模型枚举基础实体类简单字典接口工厂策略模式 接口设计AiJobProcessorAiJobProcessorFactory观察者模式AI任务相关的EventMyEventListenerMyEventPubLisherRedissonConfig定时任务实现ReplicateJobProcessorR…

printf函数格式化输出攻略

目录 一、基本用法 二、占位符 基本用法 常用占位符 字符串占位符示例 多占位符示例 注意事项 三、占位符列表 基本数据类型占位符 浮点数占位符 特殊类型占位符 长度修饰符 使用示例 注意事项 四、输出格式 1、限定宽度 基本用法 左对齐输出 浮点数宽度限制…

AI小智单片机esps32-s3烧录教程

1. 下载代码到本地 代码地址&#xff1a;https://github.com/78/xiaozhi-esp32 2. vscode安装环境 安装一下这个插件 3. esp32-s3通过数据线连接电脑 【图片】 4. vscode选择对应配置 如果是用自己的服务还得改下地址 5. 点击构建 6. 点击烧录