什么是 装饰器模式?
动态的 给某个对象添加额外的功能;python中可以使用装饰器 完成此模式; python装饰器可以 给不同对象 添加相同的功能,甚至一个对象 添加多个装饰器功能,使 其灵活匹配;
而 一般 添加额外的功能的方法 如 继承 会导致子类的所有实例化对象都含有 额外功能,有时 我们并不想这样; 或者 直接在 类中添加额外的功能方法,但是 这样 不利于 其他对象的 功能复用;
生活中的例子:
- 比如 给 狙击枪 通过 消音器 增加消音的功能;并且 消音功能 可以增加 到 不同种类的枪上(忽略消音器样式不同)
- 给 各种 战斗机增加 隐身图层功能;
代码中的例子(何时该使用此模式):
- flask框架 路由表示 通过 如下方式(给每个 函数增加 路由匹配的功能):
@app.route('/admin/login')
def admin_login():
return 'xxx'
该模式关键的角色:
- 被装饰 对象
- 装饰器
该模式的主要优缺点如下:
优点:
- 你无需创建新子类即可扩展对象的行为。
- 你可以在运行时添加或删除对象的功能。
- 你可以用多个装饰封装对象来组合几种行为。
- 单一职责原则。 你可以将实现了许多不同行为的一个大类拆分为多个较小的类。 或者一个装饰器 实现一个功能
缺点:
- 实现行为不受装饰栈顺序影响的装饰比较困难。
示例代码部分
通过 python装饰器实现 及函数实现方式
# -*- coding: utf-8 -*-
"""
(C) Guangcai Ren
All rights reserved
create time '2020/11/3 09:56'
Usage:
装饰器模式
"""
import time
from functools import wraps
def timing_decorator(func):
"""
计算 耗时 装饰器
:param func:
:return:
"""
@wraps(func)
def timeing(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
print(f'{func.__name__} 耗时:{time.time() - start_time} s')
return result
return timeing
def log_decorator(func):
"""
记录 日志 装饰器
:param func:
:return:
"""
@wraps(func)
def log_recode(*args, **kwargs):
print(f'{func.__name__} 记录日志')
return func(*args, **kwargs)
return log_recode
def calculate(a, b):
"""
相加 函数
:param a:
:param b:
:return:
"""
return a + b
@timing_decorator
@log_decorator
def equal(a, b):
"""
判断是否相等
:param a:
:param b:
:return:
"""
return a == b
if __name__ == '__main__':
# 在 对 被装饰 函数 的 包(比如第三方安装包)无法进行修改时 使用此方式 增加额外功能
# 添加一个 装饰器
cal = log_decorator(calculate)
res = cal(1, 1)
print(res)
# 添加多个 装饰器
cal = timing_decorator(log_decorator(calculate))
res = cal(1, 1)
print(res)
print('*' * 10)
# 直接在被装饰 函数 上添加装饰器
res = equal(1, 1)
print(res)
总结:
装饰器模式 在python语言中 可以通过 内置的 装饰器 语法特性 高效快速的实现; 也可使用 继承方式 实现 或 对象组合方式实现;
相关链接: