【Python笔记-设计模式】装饰器模式

一、说明

装饰器模式是一种结构型设计模式,旨在动态的给一个对象添加额外的职责。

(一) 解决问题

不改变原有对象结构的情况下,动态地给对象添加新的功能或职责,实现透明地对对象进行功能的扩展。

(二) 使用场景

  • 如果用继承来扩展对象行为的方案难以实现或者根本不可行时,可以考虑使用装饰器模式。
  • 希望在无需修改代码的情况下即可使用对象, 且希望在运行时为对象新增额外的行为。

二、结构

  1. 部件(Component)声明封装器和被封装对象的公用接口。
  2. 具体部件(Concrete Component)类是被封装对象所属的类。它定义了基础行为,但装饰类可以改变这些行为。
  3. 基础装饰(Base Decorator)类拥有一个指向被封装对象的引用成员变量。该变量的类型应当被声明为通用部件接口,这样它就可以引用具体的部件和装饰。装饰基类会将所有操作委派给被封装的对象。
  4. 具体装饰类(Concrete Decorators)定义了可动态添加到部件的额外行为。具体装饰类会重写装饰基类的方法,并在调用父类方法之前或之后进行额外的行为。
  5. 客户端(Client)可以使用多层装饰来封装部件,只要它能使用通用接口与所有对象互动即可。

三、伪代码

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
__doc__ = """
装饰器模式

例:实现咖啡店的订单系统,不同种类的咖啡可以搭配不同的调料,使用装饰器对原有对象 增加相应配料信息和价格
"""


class Coffee:
    """基础组件类 - 咖啡"""

    def cost(self):
        return 9.9


class Espresso(Coffee):
    """具体组件类 - 浓缩咖啡"""

    def cost(self):
        return super().cost() + 1

    def description(self):
        return "浓缩咖啡"


class Decorator(Coffee):
    """装饰器基类 - 调料"""

    def __init__(self, coffee):
        self._coffee = coffee

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

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


class Milk(Decorator):
    """具体装饰器类 - 牛奶"""

    def cost(self):
        return super().cost() + 2

    def description(self):
        return super().description() + " + 牛奶"


class Sugar(Decorator):
    """具体装饰器类 - 糖"""

    def cost(self):
        return super().cost() + 0.5

    def description(self):
        return super().description() + " + 糖"


# 客户端代码
if __name__ == "__main__":
    """
    浓缩咖啡 (10.9 💰)
    浓缩咖啡 + 牛奶 (12.9 💰)
    浓缩咖啡 + 牛奶 + 糖 (13.4 💰)
    """
    coffee = Espresso()
    print(f"{coffee.description()} ({coffee.cost()} 💰)")

    # 加入牛奶
    coffee_with_milk = Milk(coffee)
    print(f"{coffee_with_milk.description()} ({coffee_with_milk.cost()} 💰)")

    # 再加入糖
    coffee_with_sugar = Sugar(coffee_with_milk)
    print(f"{coffee_with_sugar.description()} ({coffee_with_sugar.cost()} 💰)")

四、优缺点

优点

  • 灵活性高:装饰器模式可以动态地给一个对象添加额外的功能,而不需要改变其结构
  • 单一职责原则。 你可以将实现了许多不同行为的一个大类拆分为多个较小的类。
  • 提高了代码复用性:可以将装饰器类与具体的组件类分开,使得装饰器类可以复用于不同的组件类。

缺点

  • 顺序对功能影响:装饰器的顺序会影响最终的功能效果,可能会导致功能组合的结果不可预测,需要谨慎设计装饰器的顺序。
  • 增加了系统复杂性

 跳转主页:【Python笔记】设计模式-CSDN博客

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

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

相关文章

python 3.7.3的安装

参考 Linux安装Python3.7-良许Linux教程网 (lxlinux.net) 1、Index of /ftp/python/3.7.9/ 1、安装gcc,yum -y install gcc 2、 yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel…

主流开发语言和开发环境:探索编程世界的基础

在当今这个快速发展的技术时代,软件开发已经成为推动创新的重要力量。无论是构建下一代应用、开发先进的算法还是创建复杂的系统,选择合适的编程语言和开发环境都是至关重要的。在本文中,我们将探讨当前流行的几种主流开发语言以及它们常用的…

展锐S8000安卓核心板参数_紫光展锐5G核心板模块定制方案

展锐S8000核心板模块是基于八核S8000平台开发设计的,采用了先进的6nm EUV制程技术。搭载了全新的智能Android 13操作系统,展现出超强的画面解析能力和高性能双通道MIPI,拥有120Hz高刷新率,独立NPU和3.2TOPS Al算力,同时…

python实现维特比算法

对于维特比算法,首先想到的就是高通公司,对于现在的通信行业的两大巨头公司之一,高通公司的发家是由器创始人维特比发明了一种高效的通信解码技术,维特比算法。 对于维特比算法是什么,以一个例子来讲述什么是维特比算…

Xcode中App图标和APP名称的修改

修改图标 选择Assets文件 ——> 点击Applcon 换App图标 修改名称 点击项目名 ——> General ——> Display Name

问题慢慢解决-通过android emulator调试android kernel-内核条件断点遇到的问题和临时解决方案

起因 在摸索到这个方案之后,mac m1调试aarch64 android kernel最终方案,就准备调试内核了,预备下断点的地方是 b binder_poll b ep_ptable_queue_proc b remove_wait_queue但是由于是android系统,上面三个函数会被频繁的触发&am…

新代码质量评审标准与评分表格

前面发了一个《代码质量评审标准与评分表格》,是比较宽泛的,下面发一个更贴近具体场景的《新代码质量评审标准与评分表格》。 一、引言 本文档旨在为代码质量评审提供一个统一的标准和评分机制,以确保代码质量、可读性和可维护性。通过遵循这…

单片机04__基本定时器__毫秒微秒延时

基本定时器__毫秒微秒延时 基本定时器介绍(STM32F40x) STM32F40X芯片一共包含14个定时器,这14个定时器分为3大类: 通用定时器 10个 TIM9-TIM1和TIM2-TIM5 具有基本定时器功能, 还具有输入捕获,输出比较功…

桥接模式:解耦抽象与实现,实现灵活多变的扩展结构

文章目录 一、引言二、应用场景与技术背景三、模式定义与实现四、实例详解五、优缺点分析总结: 一、引言 ​ 桥接模式是一种结构型设计模式,它将抽象部分与它的实现部分分离,使它们可以独立变化。这种模式通过创建一个抽象层和实现层的结构&…

普中51单片机学习(DS1302)

DS1302时钟 DS1302实时时钟具有能计算2100年之前的秒、分、时、日、日期、星期、月、年的能力,还有闰年调整的能力。内部含有31个字节静态RAM,可提供用户访问。采用串行数据传送方式,使得管脚数量最少,简单SPI 3线接口。工作电压…

初识表及什么是数据表

一、了解表 1.1.概述 表是处理数据和建立关系型数据库及应用程序的基本单元,是构成数据库的基本元素之一,是数据库中数据组织并储存的单元,所有的数据都能以表格的形式组织,目的是可读性强。 1.2.表结构简述 一个表中包括行和列…

下载 axios.js 文件到本地【linux】

方式一 npm install axios在$NODE_PATH/node_modules/axios/dist路径下即可找到axios.js。 方式二 1、百度搜索 GitHub 官网:https://github.com/ 2、搜索 axios 3、点击 axios/axios 4、下载到本地 5、解压,进入到 dist 文件夹** 参考&#x…

实现可拖拽的页面元素排序更新数据库排序

摘要: 拖拽列表改变路边排序,并且更新后台数据库列表的排序,重新请求的时候获取拖拽后的排序! Layui: // 拖拽内页顺序list document.querySelector(#view_side_tab);// 创建cruentItem存放将要拖动的元素let cruen…

Zookeeper经典应用场景实战

Zookeeper经典应用场景实战 ZK的不足之处 watcher检测是一次性的,每次触发之后都需要重新注册会话超时之后没有实现重连机制异常处理繁琐仅提供byte数组类型的接口,没提供java实体序列化级接口创建节点时如果抛出异常,需要自行检查节点是否…

【深度学习】Pytorch教程(十):PyTorch数据结构:4、张量操作(1):张量形状操作

文章目录 一、前言二、实验环境三、PyTorch数据结构1、Tensor(张量)1. 维度(Dimensions)2. 数据类型(Data Types)3. GPU加速(GPU Acceleration) 2、张量的数学运算1. 向量运算2. 矩阵…

【MySQL】多表操作、事务、索引

MySQL MYSQL 多表设计 一对多插入测试数据外键约束(物理外键)使用逻辑外键 MYSQL 多表设计 一对一表结构 MYSQL 多表设计 多对多 MYSQL 多表设计 一对多 建表语句 员工表 CREATE TABLE tb_emp (id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT COMMENT ID,username VARCHAR(20) N…

130 如何通过vs2017开发linux c++程序

使用VS2017开发linux下的应用程序(C/C)_vc_linux.exe vs2017-CSDN博客 参考上面这哥们的,写的很详细 前言 本文章记录如何使用VS2017进行linux应用程序的开发(针对新手小白),VS2017能较为方便的通过SSH编辑…

强大的文本绘图——PlantUML

PlantUML是一款开源工具,它允许用户通过简单的文本描述来创建UML图(统一建模语言图)。这种方法可以快速地绘制类图、用例图、序列图、状态图、活动图、组件图和部署图等UML图表。PlantUML使用一种领域特定语言(DSL)&am…

【Java程序设计】【C00282】基于Springboot的校园台球厅人员与设备管理系统(有论文)

基于Springboot的校园台球厅人员与设备管理系统(有论文) 项目简介项目获取开发环境项目技术运行截图 项目简介 这是一个基于Springboot的校园台球厅人员与设备管理系统 本系统分为系统功能模块、管理员功能模块以及用户功能模块。 系统功能模块&#xf…

【可申请试用】RT-Thread专业版全面支持瑞芯微RK3568系列平台并可实现混合部署...

RT-Thread 专业版是面向任务关键领域的高安全实时操作系统,已被广泛应用于航空航天,电力,轨交,车载,工业控制,新能源,医疗等国家重要领域,是各领域高可靠装备的基础核心软件。该版本…