装饰器模式:动态扩展对象功能的设计艺术

news2024/12/28 18:01:42

在面向对象设计中,装饰器模式是一种灵活的结构型模式,用于在不修改对象的基础上,动态地给一个对象添加额外的职责。这种模式通过创建一个包含原始对象的包装对象来实现功能的扩展,是继承关系的一个替代方案。本文将详细介绍装饰器模式的概念、实现方式、应用场景以及优缺点。
在这里插入图片描述

1. 装饰器模式的定义

装饰器模式(Decorator Pattern),也被称为包装器(Wrapper),允许向一个现有的对象添加新的功能,同时又不改变其结构。这种模式创建了一个装饰类,用来包装原有的类,并在保持原类方法签名完整性的前提下,提供了额外的功能。

2. 实现装饰器模式

在Python中,装饰器模式可以通过使用类来实现,这些类包装了其他类的实例。以下是一个装饰器模式的简单实现示例:

class Component:
    """定义一个操作接口"""
    def operation(self):
        pass

class ConcreteComponent(Component):
    """具体实现类,实现了组件接口"""
    def operation(self):
        print("ConcreteComponent: Basic operation.")

class Decorator(Component):
    """装饰器抽象类,持有一个Component对象的引用,并定义一个与Component接口一致的接口"""
    def __init__(self, component):
        self._component = component

    def operation(self):
        self._component.operation()

class ConcreteDecoratorA(Decorator):
    """具体装饰器A,添加额外的功能"""
    def operation(self):
        print("ConcreteDecoratorA: Extended functionality before.")
        super().operation()
        print("ConcreteDecoratorA: Extended functionality after.")

class ConcreteDecoratorB(Decorator):
    """具体装饰器B,添加额外的功能"""
    def operation(self):
        print("ConcreteDecoratorB: Extended functionality before.")
        super().operation()
        print("ConcreteDecoratorB: Extended functionality after.")

# 客户端代码
component = ConcreteComponent()
decorator1 = ConcreteDecoratorA(component)
decorator2 = ConcreteDecoratorB(decorator1)
decorator2.operation()

3. 装饰器模式的应用实例

装饰器模式在软件开发中广泛应用于以下场景:

  • 动态添加功能:在运行时为对象添加额外的功能。
  • 维护旧代码:为旧的或不可修改的代码添加新功能。
  • 功能组合:通过不同的装饰器以多种方式组合这些功能。

4. 优点和缺点

优点:

  • 提高了类的扩展性和灵活性,不需要通过修改现有的代码就可以增强对象。
  • 符合单一职责原则,每个装饰类完成的只是单一的功能添加。
  • 符合开闭原则,易于扩展与维护。

缺点:

  • 使用装饰器模式会增加系统的复杂性,可能会引入多层装饰,使系统维护更加困难。
  • 多层装饰的使用可能会使系统性能受到一定影响。

5. 总结

装饰器模式是一个非常有用的工具,适用于那些需要动态地给对象添加职责的场景。它提供了一种灵活的替代扩展功能的方法,比继承更加灵活。正确的使用装饰器模式可以使系统更加灵活,易于扩展和维护。

更多Python编程相关文章:cpython666.github.io

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

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

相关文章

循序渐进丨MogDB 数据库带级联从库的集群切换后如何保持原有架构?

生产数据库运行过程中可能会涉及到升级或者打补丁,导致各节点的角色有计划的发生改变。如果集群内角色发生改变,是否还能保持原有架构继续对外提供服务呢?我们来做一下测试。 采用22模式模拟同城两机房部署4节点 MogDB 数据库集群&#xff0c…

FFmpeg: 简易ijkplayer播放器实现--06封装打开和关闭stream

文章目录 流程图stream openstream close 流程图 stream open 初始化SDL以允许⾳频输出;初始化帧Frame队列初始化包Packet队列初始化时钟Clock初始化音量创建解复用读取线程read_thread创建视频刷新线程video_refresh_thread int FFPlayer::stream_open(const cha…

Linux/Tenten

Tenten Enumeration Nmap 扫描发现对外开放了22和80端口,使用nmap详细扫描这两个端口 ┌──(kali㉿kali)-[~/vegetable/HTB/Tenten] └─$ nmap -sC -sV -p 22,80 -oA nmap 10.10.10.10 Starting Nmap 7.93 ( https://nmap.org ) at 2023-12-25 00:52 EST Nmap …

【Python】什么是pip,conda,pycharm,jupyter notebook?conda基本教程

pip--conda--pycharm--jupyter notebook 🍃pip🍃conda🍃Pycharm🍃jupyter notebook🍃Conda基本教程☘️进入base环境☘️创建一个新的环境☘️激活环境☘️退出环境☘️查看电脑上都安装了哪些环境☘️删除已创建的项目…

Zookeeper实现分布式锁的分析和理解

Zookeeper实现分布式锁 创建临时顺序节点执行create -e -s /znode即可实现分布式锁。 zk中锁的分类 读锁(读锁共享):大家都可以读。上锁前提:之前的锁没有写锁写锁(写锁排他):只有得到写锁的…

Project Euler_Problem 172_Few Repeated Digits_动态规划

原题目: 题目大意:18位数里头,有多少个数,对于每个数字0-9,在这18位里面出现均不超过3次 111222333444555666 布星~~ 112233445566778899 可以~~ 解题思路: 动态规划 代码: ll F[19][3000000];void …

【python】在pycharm创建一个新的项目

双击打开pycharm,选择create new project 选择create,后进入项目 右键项目根目录,选择new一个新的python file 随意命名一下 输入p 然后后面就会出现智能补全提示,此时轻敲一下tab,代码就写好了,非常的方便 右键执行一下代码,下面两个直接运行和debug运行都是可以的 小结 …

使用Python批量将PDF转Word

简述 以下全部代码无法完美对图片、表格等非文字形式的内容转化。要较好的效果需要使用光学字符分析等方法进行转化 我懒,不想将代码模块拆分出来写注释 除代码1中有详细注释外,剩下的代码仅在关键部分进行注释 代码1:小规模文件的转换 代码…

C++设计模式|创建型 1.单例模式

1.什么是单例模式? 单例模式的的核⼼思想在创建类对象的时候保证⼀个类只有⼀个实例,并提供⼀个全局访问点来访问这个实例。 只有⼀个实例的意思是,在整个应⽤程序中,只存在该类的⼀个实例对象,⽽不是创建多个相同类…

spring boot整合Redis监听数据变化

一、前言 Redis提供了数据变化的通知事件,可以实时监测key和value的变化,客户端可以通过订阅相关的channel来接收这些通知事件,然后做相应的自定义处理,详细的介绍可以参考官方文档Redis keyspace notifications | Docs 使用Red…

NLP问答系统:使用 Deepset SQUAD 和 SQuAD v2 度量评估

目录 一、说明 二、Deepset SQUAD是个啥? 三、问答系统(QA系统),QA系统在各行业的应用及基本原理 3.1 医疗 3.2 金融 3.3 顾客服务 3.4 教育 3.5 制造业 3.6 法律 3.7 媒体 3.8 政府 四、在不同行业使用QA系统的基本原理 五、关于…

uniapp uview里面的u-navbar结合u-sticky组件的使用

导航栏自定义加需要吸顶产生的问题 如上图直接使用并不能出现tab栏吸顶效果&#xff0c;那是由于u-sticky组件吸顶时与顶部的距离默认为0 那么做如下处理 <u-sticky :offset-top"navbarHeight()"><u-tabs :list"helpTabList" active-color"…

Excel/WPS超级处理器,提取汉字/字母/数字

在职场工作中&#xff0c;经常会遇到单元格中有汉字&#xff0c;数字&#xff0c;字母三者的自由组合&#xff0c;但往往只需要其中的一者&#xff0c;如何快速提取呢&#xff0c;超级处理器&#xff0c;提供了4个功能可选。 超级处理器下载与安装 1&#xff09;分离字符 将…

【MySQL】事务篇

SueWakeup 个人主页&#xff1a;SueWakeup 系列专栏&#xff1a;学习技术栈 个性签名&#xff1a;保留赤子之心也许是种幸运吧 目录 本系列专栏 1. 什么是事务 2. 事务的特征 原子性&#xff08;Atomicity&#xff09; 一致性&#xff08;Consistency&#xff09; 隔离性&…

【MYSQL】索引机制概述

由于MySQL是作为存储层部署在业务系统的最后端&#xff0c;所有的业务数据最终都要入库落盘&#xff0c;但随着一个项目在线上运行的时间越来越久&#xff0c;数据库中的数据量自然会越来越多&#xff0c;而数据体积出现增长后&#xff0c;当需要从表查询一些数据时&#xff0c…

Argus DBM 一款开源的数据库监控工具,无需部署Agent

开箱即用 无需部署Agent&#xff0c;开箱即用。我们使用JDBC直连您的数据库&#xff0c;输入IP端口账户密码即可。 全平台支持 Argus目前支持对Mysql, PostgreSQL, Oracle等数据库类型的监控&#xff0c;我们也会尽快适配其它数据库&#xff0c;致力于监控所有数据库。我们提…

数仓维度建模

维度建模 数仓建模方法1. 范式建模法&#xff08;Third Normal Form&#xff0c;3NF&#xff09;2. 维度建模法&#xff08;Dimensional Modeling&#xff09;3. 实体建模法&#xff08;Entity Modeling&#xff09; 维度建模1. 事实表事实表种类事务事实表周期快照事实表累计快…

淘宝扭蛋机小程序:扭出惊喜,乐享购物新体验

在快节奏的现代生活中&#xff0c;人们总是在寻找新鲜、有趣的娱乐方式。淘宝扭蛋机小程序应运而生&#xff0c;为您带来前所未有的购物与娱乐结合新体验。在这里&#xff0c;每一次的扭动都充满惊喜&#xff0c;每一次的点击都带来乐趣&#xff0c;让您在购物的同时&#xff0…

VRRP(虚拟路由冗余协议)详解

VRRP-------虚拟路由冗余协议 在一个网络中&#xff0c;要做为一个合格的网络首先就要具备几种冗余&#xff0c;增加网络的可靠性。 这几种冗余分别为&#xff1a;线路冗余&#xff0c;设备冗余&#xff0c;网关冗余&#xff0c;UPS冗余 VRRP该协议就是解决网关冗余的。在二层…

总分410+专业130+国防科技大学831信号与系统考研经验国防科大电子信息与通信工程,真题,大纲,参考书。

好几个学弟催着&#xff0c;总结一下我自己的复习经历&#xff0c;希望大家复习少走弯路&#xff0c;投入的复习正比换回分数。我专业课831信号与系统130&#xff08;感觉比估分要低&#xff0c;后面找Jenny老师讨论了自己拿不准的地方也没有错误&#xff0c;心里最近也这经常回…