装饰器设计模式是什么?什么是 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 = coffee

    def cost(self):
        return self._coffee.cost()

# ConcreteDecorator 具体装饰器类
class Milk(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 2

class Sugar(CoffeeDecorator):
    def cost(self):
        return self._coffee.cost() + 1

# 使用示例
coffee = SimpleCoffee()
print(coffee.cost())  # 输出:5

coffee_with_milk = Milk(coffee)
print(coffee_with_milk.cost())  # 输出:7

coffee_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_page

    def 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 Page

bold_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♪(・ω・)ノ 🍇

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

httpd(Web服务器)

名词解释 1、URL&#xff1a;Uniform Resource Locator&#xff0c;统⼀资源定位符 2、⽹址格式&#xff1a;<协议>://<主机或主机名>[:port]/<⽬录资源,路径> 3、主机地址/主机名&#xff1a;主机地址是服务器在因特⽹所在的IP地址。主机名就需要域名解析…

用于计算机屏幕安全摄像头系统:Screen Anytime Crack

Screen Anytime 是一款软件&#xff0c;旨在自动将整个用户会话或 PC/服务器/VM/Kiosk 的 /RDP/Citrix/RemoteApp 会话的屏幕活动记录到视频日志文件中&#xff0c;以用于记录、审核和监控目的。通过重播其高度压缩的视频&#xff0c;您可以轻松回顾单台计算机或一组服务器/PC …

Power Apps-下拉列表控件

插入一个下拉列表控件 设置值的两种方式 1.通过属性items写数组设置 2.通过连接数据表&#xff0c;先在右侧操作面板中选择项目中的数据表 再从Value中选择其中一列&#xff0c;下拉就可以选择该列全部行的值 但是这样会导致有很多重复的字段&#xff0c;所以可以在items属性里…

最近技术圈发生了很多大事,来聊聊

如标题所说&#xff0c;最近这几年全球都大事频发。有事甚至不知道是我更关心社会和时政、还是真的进入一个大变革时代。 可以确认的是&#xff0c;现在这个时代、科技的发展到了一个可感知到越来越快的速度。 … 前几天&#xff0c;当下AI 领域最有知名的人奥特曼被 OpenAI…

Leaflet实现轨迹播放动画效果

效果图如下&#xff1a; <!DOCTYPE html> <html><head><title>轨迹</title><meta charset"utf-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><!-- 引入样式 -->…

Sentinel 授权规则 (AuthorityRule)

Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 SpringbootDubboNacos 集成 Sentinel&…

基于深度学习的文本分类

通过构建更复杂的深度学习模型可以提高分类的准确性&#xff0c;即分别基于TextCNN、TextRNN和TextRCNN三种算法实现中文文本分类。 项目地址&#xff1a;zz-zik/NLP-Application-and-Practice: 本项目将《自然语言处理与应用实战》原书中代码进行了实现&#xff0c;并在此基础…

Connect-The-Dots_2

Connect-The-Dots_2 一、主机发现和端口扫描 主机发现&#xff0c;靶机地址192.168.80.148 arp-scan -l端口扫描 nmap -A -p- -sV 192.168.80.148开放端口 21/tcp open ftp vsftpd 2.0.8 or later 80/tcp open http Apache httpd 2.4.38 ((Debian)) 111/tcp …

前缀和——DP34 【模板】前缀和

文章目录 &#x1f34b;1. 题目&#x1f348;2. 算法原理&#x1f348;3. 代码实现 &#x1f34b;1. 题目 题目链接&#xff1a;【模板】前缀和_牛客题霸_牛客网 (nowcoder.com) 描述 给定一个长度为n的数组a1,a2,…an. 接下来有q次查询, 每次查询有两个参数l, r. 对于每个询…

基于ZLMediaKit的GB28181视频平台demo

GB28181 主要内容 国标的20位id是按照标准来定的&#xff0c;前8位是地域信息&#xff0c;9-10位是行业信息&#xff0c;11-13是设备类型、14是网络标识、后6位为序号 约定以SIP协议作为会话通道的使用标准&#xff0c;以RTP作为语言和视频的载体。联网系统在进行音视频传输及…

ui设计师简历自我评价的范文(合集)

ui设计师简历自我评价的范文篇一 本人毕业于艺术设计专业&#xff0c;具有较高的艺术素养&#xff0c;平时注重设计理论知识的积累&#xff0c;并将理论应用到作品中。了解当下设计的流行趋势&#xff0c;设计注重细节、重视用户体验&#xff0c;对色彩搭配有着浓厚的兴趣&…

简墨的进化之路:打造大模型数据计算系统的云存储底座

10月24日程序员节&#xff0c;「大模型数据计算系统」2023拓数派年度技术论坛在上海圆满落幕&#xff0c;拓数派大模型数据计算系统&#xff08;PieDataComputingSystem&#xff0c;缩写&#xff1a;πDataCS&#xff09;如约而至&#xff01;πDataCS 以云原生技术重构数据存储…

私有化敏感词检测API服务wordscheck

之前有网友在找敏感词检测的应用&#xff0c;这个应该能满足他的需求&#xff1b; 什么是 wordscheck &#xff1f; wordscheck 是敏感词检测 API&#xff0c;提供文本识别、智能鉴黄、涉政检测、谩骂等等敏感词检测过滤服务。 简介 敏感词库从大量样本库整理出来&#xff0c;…

Java 编码

编码: 加密: 通过加密算法和密钥进行 也可通过码表进行加密 对称加密: 缺点:可被截获 元数据---加密算法密钥密文 ----> 解密算法密钥元数据 算法:DES(短 56位),AES(长 128位)破解时间加长 非对称加密: 元数据-加密算法加密密钥 密文 --->加密算法解密密钥元数据 …

1.Qt5.15及其以上的下载

Qt5.15及其以上的下载 简介&#xff1a; ​ Qt是一个跨平台的C库&#xff0c;允许开发人员创建在不同操作系统&#xff08;如Windows、macOS、Linux/Unix&#xff09;和设备上具有本地外观和感觉的应用程序。Qt提供了一套工具和库&#xff0c;用于构建图形用户界面&#xff0…

CNVD-2023-12632:泛微E-cology9 browserjsp SQL注入漏洞复现 [附POC]

文章目录 泛微E-cology9 browserjsp SQL注入漏洞(CNVD-2023-12632)漏洞复现 [附POC]0x01 前言0x02 漏洞描述0x03 影响版本0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 0x06 修复建议 泛微E-cology9 browserjsp SQL注入漏洞(CNVD-2023-12632)漏洞复现 [附POC] 0x…

JavaEE 多线程01

为什么引入多线程? 首先进程已经能很好的完成多任务这个情景下的并发编程了,那为什么又引入多线程呢? 这是因为在一些情景下,我么需要大量的创建和销毁进程来完成一些任务,此时多进程对系统的开销就会很大了. 假设有这样一个场景,服务器同时接收到很多个服务请求,这个时候服务…

数据挖掘 K近邻

什么时候用K近邻&#xff1f; 交叉验证的时候。最常见的交叉验证方法是K折交叉验证&#xff0c;其中数据集被均匀分成K个子集&#xff0c;称为折&#xff0c;然后执行K次训练和测试&#xff0c;每次选择不同的折作为测试集&#xff0c;其余的作为训练集。最后&#xff0c;将K次…

windows11快速输入时间和日期

windows11快速输入时间和日期 〇、赶时间的看这里 任务栏微软输入法图标右键 | 设置 | 词库和自学习 | 用户自定义短语 |添加或编辑自定义短语| 添加日期设置 %yyyy%-%MM%-%dd%时间设置 %yyyy%-%MM%-%dd% %HH%:%mm%:%ss%-------------------------------------------------…

ROS1创建自定义服务并使用

1.首先在功能包创建一个srv文件夹 如上图所示&#xff0c;vehicle_control是我的功能包&#xff0c;创建一个srv文件夹 2.使用touch指令创建服务文件 touch Ranging.srv3.在文件内输入服务数据 横线代表分割符&#xff0c;上面的是客户端发送的数据&#xff0c;下面是服务器…