漫谈设计模式 [8]:装饰器模式

server/2024/9/23 20:30:49/

引导性开场

菜鸟:老鸟,我最近在项目中遇到一个问题。有些功能,比如日志记录和权限校验,我需要在多个地方使用。代码很冗余,不知道有没有更好的解决办法?

老鸟:菜鸟,这个问题很常见。你有没有听说过设计模式中的装饰器模式

菜鸟装饰器模式?听说过一点,但不太明白具体怎么用。

老鸟:没关系,咱们一步一步来。装饰器模式可以帮你解决这个问题。我们先从头说起。

渐进式介绍概念

老鸟:想象一下,你有一个简单的汉堡,只有面包和肉。现在你想加一些配料,比如生菜、番茄和奶酪。你可以一个个地加上去,这样就能得到一个更丰富的汉堡。装饰器模式就像是给汉堡加配料,逐步增强它的功能。

菜鸟:哦,这样说我就明白一点了。那代码里该怎么实现呢?

老鸟:我们先写一个最基本的函数,然后再逐步加上装饰器。

Python代码示例,逐步展开

基础实现

老鸟:假设我们有一个最简单的函数,它只是打印一句话。

python">def greet():print("Hello, World!")

菜鸟:这个很简单,那怎么加上装饰器呢?

引入装饰器

老鸟:我们来写一个装饰器函数,它在原函数前后加上一些日志记录。

python">def log_decorator(func):def wrapper():print("Logging start...")func()print("Logging end...")return wrapper

菜鸟:那这个装饰器怎么用在 greet 函数上呢?

老鸟:我们可以这样:

python">@log_decorator
def greet():print("Hello, World!")

菜鸟:然后直接调用 greet() 就行了吗?

老鸟:对,试试看。

python">greet()

菜鸟:输出结果是:

Logging start...
Hello, World!
Logging end...

扩展功能

老鸟:现在我们再加一个装饰器,比如权限校验。

python">def auth_decorator(func):def wrapper():print("Checking permissions...")func()return wrapper

菜鸟:那怎么同时使用两个装饰器呢?

老鸟:你可以这样:

python">@log_decorator
@auth_decorator
def greet():print("Hello, World!")

菜鸟:直接调用 greet() 会输出:

Logging start...
Checking permissions...
Hello, World!
Logging end...

问题与反思

菜鸟:这样做确实方便,但如果我不用装饰器,直接在函数里加这些功能也可以吧?

老鸟:当然可以,但这样代码会很冗余,而且不易维护。如果你需要在多个地方使用这些功能,装饰器模式会更优雅和灵活。

菜鸟:确实,如果直接在函数里加,会导致代码重复,修改起来也麻烦。

优势与适用场景

老鸟装饰器模式的优势在于它能动态地为对象添加功能,而不修改对象本身。适用场景包括:

  1. 日志记录:在函数执行前后记录日志。
  2. 权限校验:检查用户权限。
  3. 性能监控:记录函数的执行时间。
  4. 事务管理:在函数执行前后处理事务。

常见误区与优化建议

菜鸟:那使用装饰器模式有什么需要注意的吗?

老鸟:常见误区包括:

  1. 过度使用:不必要的装饰器会增加代码复杂度。
  2. 嵌套过深:多个装饰器嵌套会导致代码难以理解。

优化建议:

  1. 保持简单:每个装饰器只做一件事。
  2. 良好命名:给装饰器和函数起有意义的名字,便于理解。

总结与延伸阅读

老鸟:总结一下,装饰器模式是一种结构型设计模式,可以动态地为对象添加功能,而不改变其结构。它的优势在于灵活性和可维护性,适用于日志记录、权限校验等场景。

菜鸟:谢谢老鸟,今天学到了很多!有没有推荐的书或资料可以进一步学习?

老鸟:可以看看《设计模式:可复用面向对象软件的基础》这本书,还有Python的官方文档里关于装饰器的部分。

菜鸟:太好了,我回去就开始学习!下次再请教你其他设计模式

老鸟:随时欢迎!


http://www.ppmy.cn/server/113494.html

相关文章

pytorch tensor.expand函数介绍

在 PyTorch 中,tensor.expand()是一个用于扩展张量维度的函数。 一、函数作用 它允许你在不复制数据的情况下,将张量的形状扩展到指定的维度大小。这对于需要在特定维度上重复数据的操作非常有用,例如在进行广播操作时调整张量的形状。 二…

环球佳酿:如何利用CRM系统实现营销管理数字化转型

在科技迅猛发展的今天,传统行业正在以空前的速度与数字技术相融合。面对从增量扩张转向存量竞争的白酒产业,培育新质生产力、推进数字化与智能化转型已成为业界的普遍共识。众多白酒企业纷纷探索数字化转型之路,力图通过创新和突破来提升竞争…

蓝桥杯备赛day02:递推

斐波那契数列 #include <bits/stdc.h> using namespace std; int main() {int n;cin>>n;int dp[n1];dp[1]1;dp[2]1;for(int i 3;i < n;i) dp[i] dp[i-1]dp[i-2];cout<<dp[n];return 0; }n int(input()) dp [0] * (n 1) dp[1] 1 if n > 1:dp[2] …

【H2O2|全栈】关于HTML(4)HTML基础(三)

HTML相关知识 目录 HTML相关知识 前言 准备工作 标签的具体分类&#xff08;三&#xff09; 本文中的标签在什么位置中使用&#xff1f; 列表 ​编辑​编辑 有序列表 无序列表 自定义列表 表格 拓展案例 预告和回顾 后话 前言 本系列博客将分享HTML相关知识点…

数学基础 -- 线性代数之格拉姆-施密特正交化

格拉姆-施密特正交化 格拉姆-施密特正交化&#xff08;Gram-Schmidt Orthogonalization&#xff09;是一种将一组线性无关的向量转换为一组两两正交向量的算法。通过该过程&#xff0c;我们能够从原始向量组中构造正交基&#xff0c;并且可以选择归一化使得向量组成为标准正交…

【B题第三套完整论文已出】2024数模国赛B题第三套完整论文+可运行代码参考(无偿分享)

基于多阶段优化的电子产品质量控制与成本管理研究 摘要 随着现代制造业和智能化生产的发展&#xff0c;质量控制和生产优化问题成为工业管理中的重要研究课题。本文针对电子产品生产过程中质量控制和成本优化中的问题&#xff0c;基于系统优化和决策分析思想&#xff0c;通过…

JVM面试真题总结(一)

文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ 文章收录在网站&#xff1a;http://hardyfish.top/ Java主要是解释执行还是编译执行?请说明理由 Java既是解释执行的…

LVS 负载均衡集群指南

1. 引言 LVS (Linux Virtual Server) 虚拟服务器&#xff0c;是 Linux 内核中实现的负载均衡技术&#xff0c;以其高性能、高可靠性和高可用性而闻名。LVS 工作在 TCP/IP 协议栈的第四层 (传输层)&#xff0c;通过将流量分配到多个后端服务器&#xff0c;提高系统性能、可用性…