装饰大师——装饰模式(Python实现)

news2024/9/20 5:59:59

大家好,今天我们继续来讲结构型设计模式,上一期我们介绍了组合模式,这个模式特别适合用于处理树形结构的问题,它能够让我们像处理单个对象一样来处理对象组合。

装饰模式(Decorator Pattern)是一种结构型设计模式,它允许向现有对象添加新的功能,同时又不改变其结构;本文将介绍装饰模式的定义、实现方法,并通过几个实际的案例展示如何在Python项目中应用装饰模式。

装饰模式概述

装饰模式的核心思想是将功能附加到对象上,而不是通过继承来实现,这种模式包含以下几个关键组成部分:

  1. 组件接口:定义基本功能;
  2. 具体组件:实现基本功能的类;
  3. 装饰器基类:实现组件接口,并包含一个指向组件对象的引用;
  4. 具体装饰器:扩展装饰器基类,实现额外的功能。

装饰模式与其他设计模式(如代理模式、适配器模式)不同之处在于,装饰模式注重动态地为对象添加职责,而不改变对象的接口。

模式结构

类图

示意图

装饰模式的Python实现

在Python中,装饰模式通常使用函数或类装饰器来实现,以下是几种常见的实现方式:

基本实现

以下是一个简单的装饰器例子,它为函数添加打印日志的功能:

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} finished")
        return result
    return wrapper

@log_decorator
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")
带参数的装饰器

装饰器还可以接受参数,从而更加灵活,以下是一个带参数的装饰器例子:

def repeat_decorator(times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(times):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat_decorator(3)
def say_hello(name):
    print(f"Hello, {name}!")

say_hello("Alice")
多层装饰器的使用

装饰器可以叠加使用,实现多层装饰:

def uppercase_decorator(func):
    def wrapper(*args, **kwargs):
        result = func(*args, **kwargs)
        return result.upper()
    return wrapper

@log_decorator
@uppercase_decorator
def greet(name):
    return f"Hello, {name}"

print(greet("Alice"))

实际应用案例

装饰模式在实际项目中有很多应用场景,例如日志记录、权限验证和性能监控等。

日志记录功能的装饰

通过装饰器为函数添加日志记录功能,可以避免在每个函数中重复写日志代码:

def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function {func.__name__}")
        result = func(*args, **kwargs)
        print(f"Function {func.__name__} finished")
        return result
    return wrapper

@log_decorator
def process_data(data):
    # 模拟数据处理逻辑
    print("Processing data...")
    return data

process_data("Sample Data")

在上述例子中,每次调用 process_data 函数时,都会记录函数调用的开始和结束时间。

权限验证功能的装饰

通过装饰器为函数添加权限验证功能,可以在调用实际业务逻辑之前进行权限检查:

def permission_required(permission):
    def decorator(func):
        def wrapper(*args, **kwargs):
            if not has_permission(permission):
                raise PermissionError("Access denied")
            return func(*args, **kwargs)
        return wrapper
    return decorator

def has_permission(permission):
    # 模拟权限验证逻辑
    allowed_permissions = ["admin", "user"]
    return permission in allowed_permissions

@permission_required("admin")
def delete_user(user_id):
    # 模拟删除用户逻辑
    print(f"User {user_id} deleted.")

try:
    delete_user(123)
except PermissionError as e:
    print(e)

在上述例子中,只有当用户具有 “admin” 权限时,才允许删除用户。

性能监控功能的装饰

通过装饰器为函数添加性能监控功能,可以方便地记录函数的执行时间:

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} took {end_time - start_time} seconds")
        return result
    return wrapper

@timing_decorator
def perform_task():
    # 模拟任务执行逻辑
    time.sleep(2)
    print("Task completed.")

perform_task()

在上述例子中,perform_task 函数的执行时间被记录下来并输出到控制台。

装饰模式的优缺点

优点
  1. 单一职责原则:可以将职责划分到不同的类中,使每个类的功能更加单一和明确;
  2. 动态扩展功能:可以在运行时添加或删除功能,而无需修改原有代码;
  3. 灵活性高:通过不同的装饰器组合,可以实现多种不同的功能扩展;
  4. 减少代码重复:可以避免在多个类中重复实现相同的功能,减少代码冗余。
缺点
  1. 增加复杂性:装饰器的嵌套使用可能会导致代码结构复杂,不易理解和维护;
  2. 调试困难:由于装饰器改变了函数的行为,调试时可能不容易追踪到问题的根源;
  3. 性能开销:多层装饰器可能会增加函数调用的开销,影响性能。

应用场景

装饰模式适用于以下场景:

  1. 需要动态添加功能:例如为已有功能添加日志记录、性能监控或权限验证等;
  2. 功能扩展频繁:例如在项目中需要经常为不同对象添加或移除功能;
  3. 不希望修改原有代码:例如在使用第三方库时,不希望直接修改其源代码,而是通过装饰器来扩展其功能;
  4. 跨切面关注点:例如在面向切面编程中,装饰模式可以用于处理日志、事务管理、异常处理等横切关注点。

总结

装饰模式通过在运行时动态地为对象添加职责,使得代码更加灵活和可扩展;尽管装饰模式带来了许多好处,但也需要注意其可能带来的复杂性,正确理解和使用装饰模式,可以有效提升代码的可维护性和可读性。

希望本文能帮助你更好地理解装饰模式及其在Python中的实现,并能在实际项目中灵活应用这一设计模式,如果你有任何疑问或想法,欢迎在下方留言!别忘了关注我们的公众号,获取更多有趣的编程知识和实用的代码技巧,我们期待与你的交流与分享!
在这里插入图片描述

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

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

相关文章

最新彩虹自助下单代发卡码知识付费商城多模板系统完整版去授权源码V6.9

最新彩虹的知识付费商城源码,后台可以选择多套模板,完整版去授权,支持对接多个资源网站,不怕无资源 推荐用宝塔上传后直接访问即可根据提示安装。 后面用户名/密码:admin/123456 PHP推荐使用7.0及以上版本 V6.9 1.修复SQL注入…

k8s 部署RuoYi-Vue-Plus之ingress域名解析

可参看https://blog.csdn.net/weimeibuqieryu/article/details/140798925 搭建ingress 1.创建Ingress对象 ingress-ruoyi.yaml其中host替换为你对应域名,需要解析域名到服务器, 同时为后端服务添加了二级域名解析 api. 访问http://xxx.xyz/就能访问前端&#xff0…

应急靶场(11):【玄机】日志分析-apache日志分析

题目 提交当天访问次数最多的IP,即黑客IP黑客使用的浏览器指纹是什么,提交指纹的md5查看index.php页面被访问的次数,提交次数查看黑客IP访问了多少次,提交次数查看2023年8月03日8时这一个小时内有多少IP访问,提交次数 …

【Redis 初阶】Redis 常见数据类型(Set、Zset、渐进式遍历、数据库管理)

一、Set 集合 集合类型也是保存多个字符串类型的元素的(可以使用 json 格式让 string 也能存储结构化数据),但和列表类型不同的是,集合中: 元素之间是无序的。(此处的 “无序” 是和 list 的有序相对应的…

重载云台摄像机如何通过国标28181接入到统一视频接入平台(视频国标接入平台)

目录 一、国标GB/T 28181介绍 1、国标GB/T28181 2、内容和特点 二、重载云台摄像机 1、定义 2、结构与设计 3、功能和优势 4、特点 5、应用场景 二、接入准备工作 1、确定网络环境 (1)公网接入 (2)专网传输 2、检查重…

软件测试基础1--功能测试

1、什么是软件测试? 软件是控制计算机硬件运行的工具。 软件测试:使用技术手段验证软件是否满足使用需求,为了发现软件功能和需求不相符合的地方,或者寻找实际输出和预期输出之间的差异。 软件测试的目的:减少软件缺陷…

golang JSON序列化

JSON JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。 它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。 json历史 [外链图片转存失败,源站可能有防盗链机…

080基于ssm+vue的大学生兼职信息系统

开发语言:Java框架:ssmJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包:Maven3.…

获客工具大揭秘:为何它能让获客如此轻松?

你是不是也觉得,现在的市场环境,获客越来越难了? 今天我要给大家分享一个实用且高效的获客工具,它简直是营销界的福音! 1、关键词搜索 关键词搜索功能是获客工具的基础,也是其重要性不可小觑的原因。 这…

【数据中台】大数据管理平台建设方案(原件资料)

建设大数据管理中台,按照统一的数据规范和标准体系,构建统一数据采集﹣治理﹣共享标准、统一技术开发体系、统一接口 API ,实现数据采集、平台治理,业务应用三层解耦,并按照统一标准格式提供高效的…

LabVIEW发电机控制器自动测试系统

随着飞机电源系统对自动化与精确控制需求的提高,开发了一套基于LabVIEW和NI PXI硬件平台的飞机发电机控制器测试系统。该系统利用先进的测试技术,实现对飞机发电机控制器的自动测试,显著提升测试的效率、精度和一致性。 项目背景 飞机发电机…

nginx反向代理+nginx黑白名单+nginx负载均衡+平滑升级+配置jdk环境-7.30

一、反向代理 1.前端服务器配置 前端服务器:用于接收和响应客户端,代理另一台主机 Nginx 安装 (1).下载安装nginx [rootweb ~]# wget https://nginx.org/download/nginx-1.26.1.tar.gz (2).解压 [rootweb ~ ]# tar -zxvf nginx-1.26.1.tar.gz (3…

《从零开始做个摸鱼小网站! · 序》灵感来源

序 大家好呀,我是summo,这次来写写我在上班空闲(摸鱼)的时候做的一个小网站的事。去年阿里云不是推出了个活动嘛,2核2G的云服务器一年只要99块钱,懂行的人应该知道这个价格在业界已经是非常良心了,虽然优惠只有一年&a…

【论文共读】【翻译】【CGAN】【Conditional Gernerative Adversarial Networks】

论文地址:https://arxiv.org/pdf/1411.1784 翻译: Conditional Gernerative Adversarial Networks 条件生成对抗网络 0. 摘要 生成对抗网络[8]最近被引入,作为一种训练生成模型的新方法。在这项工作中,我们引入了生成对抗网络的…

同步与异步,阻塞与非阻塞的深入分析

😎 作者介绍:欢迎来到我的主页👈,我是程序员行者孙,一个热爱分享技术的制能工人。计算机本硕,人工制能研究生。公众号:AI Sun(领取大厂面经等资料),欢迎加我的…

人在迷茫无聊时该干什么?

做两件事,收和放。 第一件事收,全面收缩。 迷茫不是无事可做,而是所做的事没有意义,没有意义就停掉,空出时间让身心恢复到正常状态。迷茫会让你焦虑,让你晚睡,让你狂吃,让你迫不及待…

公司里的IT是什么?

公司里的IT是什么? 文章目录 公司里的IT是什么?1、公司里的IT2、IT技术3、IT行业4、IT行业常见证书 如果对你有帮助,就点赞收藏把!(。・ω・。)ノ♡ 前段时间,在公…

ARMv8 内存属性

目录 普通内存 (normal memory)设备内存(device memory)arm64 mair_el1 系统寄存器及linux 对其配置页表中的内存属性总结 普通内存 (normal memory) 弱一致性(weakly ordered)。 存在分支预测,数据预取,高速缓存行预…

二分算法及其公式

二分查找 二分查找是大多数人第一个接触到的算法,很多人都认为只有有序的数组可以使用二分查找,但这种思想其实是错误的,二分查找是可以用于拥有二段性的数组,而且二分算法是由模板做参考的,所以只要掌握就可以解决大…

【区块链+绿色低碳】基于区块链的双碳能源纳管平台 | FISCO BCOS应用案例

在双碳战略的指导下,南京区块链产业应用协会牵头研发的双碳能源纳管平台,依托区块链、人工智能、云计算、 物联网、大数据、工业互联网与边缘计算等技术,对绿电追溯、需求侧响应、能源微网、源网荷储、隔墙用电、 碳排放权认证、额度计量、预…