【设计模式】深入解析装饰器模式(Decorator Pattern)

深入解析装饰器模式(Decorator Pattern)

一、装饰器模式的核心概念

装饰器模式是一种结构型设计模式 ,用于动态地给对象添加新功能 ,而不改变其原始代码

1. 为什么需要装饰器?

  • 避免继承带来的类爆炸问题:如果每种新功能都创建子类,组合复杂时类会爆炸式增长。
  • 支持动态扩展功能 :继承是静态 的,而装饰器可以在运行时动态添加/移除功能
  • 遵循开闭原则(OCP) :不修改原始代码,而是通过装饰器增强。

二、装饰器的核心机制

装饰器本质上就是一个高阶函数 ,它接收一个函数(或类)作为参数,返回一个新的函数(或类) ,增强原有功能。

装饰器的执行顺序

  1. 定义装饰器

    • 编写一个函数 ,接收原函数 func,在 wrapper 中增加新功能。
  2. 应用装饰器

    • 通过 @decorator 语法,把装饰器作用在目标函数上。
  3. 调用目标函数

    • 实际执行的是 wrapper(),它先执行装饰逻辑,再调用原函数

三、Python 装饰器示例

1. 计时装饰器

📌 示例:在函数运行前后打印执行时间

python 复制代码
import time

# 定义装饰器
def time_logger(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()  # 记录开始时间
        result = func(*args, **kwargs)  # 执行原函数
        end_time = time.time()  # 记录结束时间
        print(f"{func.__name__} 执行时间: {end_time - start_time:.6f} 秒")
        return result  # 返回原函数的返回值
    return wrapper  # 返回包装后的函数

# 使用装饰器
@time_logger
def slow_function():
    time.sleep(1)
    print("函数执行完毕")

slow_function()

执行流程

  1. @time_logger 作用在 slow_function 上,相当于 slow_function = time_logger(slow_function)

  2. 当调用 slow_function() 时,实际上执行的是 wrapper()

    • 记录时间 start_time
    • 调用 slow_function()
    • 最后 计算并打印执行时间。

输出示例

复制代码
函数执行完毕
slow_function 执行时间: 1.000123 秒

2. 日志装饰器

📌 示例:在函数执行前后自动记录日志

python 复制代码
def log_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"开始执行 {func.__name__},参数:{args} {kwargs}")
        result = func(*args, **kwargs)
        print(f"{func.__name__} 执行完毕,返回值:{result}")
        return result
    return wrapper

@log_decorator
def add(a, b):
    return a + b

print(add(3, 5))

执行流程

  1. @log_decoratoradd 包装成 wrapperadd 变成 wrapper 的引用。

  2. add(3, 5) 执行时:

    • 打印 "开始执行 add,参数:(3, 5) {}"
    • 运行 add(3, 5)
    • 最后 记录 "add 执行完毕,返回值:8"

输出示例

csharp 复制代码
开始执行 add,参数:(3, 5) {}
add 执行完毕,返回值:8
8

3. 组合多个装饰器

装饰器可以层层叠加,按顺序执行:

python 复制代码
@time_logger
@log_decorator
def multiply(a, b):
    time.sleep(0.5)
    return a * b

print(multiply(2, 3))

执行流程

  1. 执行 log_decorator
  2. 执行 time_logger
  3. 最后 执行 multiply

输出示例

python 复制代码
开始执行 multiply,参数:(2, 3) {}
函数执行完毕
multiply 执行时间: 0.500123 秒
multiply 执行完毕,返回值:6
6

四、JavaScript 装饰器示例

1. 计时装饰器

python 复制代码
function timeLogger(func) {
    return function (...args) {
        const startTime = Date.now();
        const result = func(...args);  // 执行原函数
        const endTime = Date.now();
        console.log(`${func.name} 执行时间: ${(endTime - startTime) / 1000} 秒`);
        return result;
    };
}

function slowFunction() {
    console.log("函数执行中...");
    for (let i = 0; i < 1e9; i++) {}  // 模拟耗时操作
    console.log("函数执行完毕");
}

const wrappedFunction = timeLogger(slowFunction);
wrappedFunction();

执行流程

  1. timeLogger(slowFunction) 返回 wrapperwrappedFunction 变成 wrapper

  2. 执行 wrappedFunction()

    • 记录 startTime
    • 执行 slowFunction()
    • 最后 计算执行时间并打印。

输出示例

python 复制代码
函数执行中...
函数执行完毕
slowFunction 执行时间: 2.345 秒

2. ES7+ 修饰器(Decorator)

在现代 JavaScript 中,可以使用 @decorator 语法

python 复制代码
function logDecorator(target, key, descriptor) {
    const originalMethod = descriptor.value;
    descriptor.value = function (...args) {
        console.log(`执行 ${key},参数:`, args);
        const result = originalMethod.apply(this, args);
        console.log(`返回值:`, result);
        return result;
    };
    return descriptor;
}

class MathOperations {
    @logDecorator
    add(a, b) {
        return a + b;
    }
}

const math = new MathOperations();
math.add(3, 5);

输出示例

python 复制代码
执行 add,参数:[3, 5]
返回值:8

五、装饰器模式 vs 代理模式

对比项 装饰器模式(Decorator) 代理模式(Proxy)
作用 增强对象功能 控制对象访问
是否修改原对象 ❌ 不修改 ❌ 只代理,通常不修改
是否拦截请求 ❌ 不拦截 ✅ 代理可拦截请求
典型应用 Vue reactive()、日志、计时 API 代理、缓存、权限控制

六、总结

  1. 装饰器模式用于动态扩展对象功能,而不修改其原始代码
  2. 装饰器本质是一个高阶函数,接收函数/类作为参数,返回一个增强版本
  3. Python @decorator 语法糖让装饰器更直观 ,JavaScript 也可以使用 @decorator(ES7+)。
  4. 适用于日志记录、权限控制、缓存优化等场景

🚀 掌握装饰器模式,让你的代码更优雅、更灵活!

相关推荐
tianyuanwo1 小时前
基于RISC-V架构的服务器OS构建DevOps体系的全方位方案
服务器·架构·risc-v
大模型学习原理2 小时前
不同AI架构如何选择?单Agent+MCP“与“多Agent“架构对比分析!
人工智能·ai·语言模型·架构·大模型·agent·ai大模型
mldong6 小时前
mldong 快速开发框架登录模块设计与实现
java·后端·架构
唐人街都是苦瓜脸8 小时前
学习Oracle------高可用架构解析
学习·oracle·架构
19898 小时前
【Dify精讲】第12章:性能优化策略与实践
人工智能·python·深度学习·性能优化·架构·flask·ai编程
lovebugs9 小时前
Java线上死锁问题实战:从定位到解决的全链路指南
java·后端·面试
TracyCoder1239 小时前
APISIX 简介:云原生 API 网关的架构与实践
云原生·架构·apisix
未来并未来10 小时前
微服务中的分布式事务
分布式·微服务·架构
198910 小时前
【Dify精讲】第14章:部署架构与DevOps实践【知识卡片】
运维·python·性能优化·架构·flask·ai编程·devops
Ann201510 小时前
SaaS+AI架构实战,
人工智能·架构