别院牧志知识库 别院牧志知识库
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
首页
  • 基础

    • 全栈之路
    • 😎Awesome资源
  • 进阶

    • Python 工匠系列
    • 高阶知识点
  • 指南教程

    • Socket 编程
    • 异步编程
    • PEP 系列
  • 面试

    • Python 面试题
    • 2025 面试记录
    • 2022 面试记录
    • 2021 面试记录
    • 2020 面试记录
    • 2019 面试记录
    • 数据库索引原理
  • 基金

    • 基金知识
    • 基金经理
  • 细读经典

    • 德隆-三个知道
    • 孔曼子-摊大饼理论
    • 配置者说-躺赢之路
    • 资水-建立自己的投资体系
    • 反脆弱
  • Git 参考手册
  • 提问的智慧
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 辨析

  • Sockets编程

  • Django

  • stackoverflow

  • Flask

  • 全栈之路

  • 面试

  • 代码片段

  • 异步编程

  • 😎Awesome资源

  • PEP

  • Python工匠系列

  • 高阶知识点

  • Python 学习资源待整理
  • 设计模式

    • Python 设计模式
    • 装饰器模式
    • 抽象工厂模式
    • 建造者模式/生成器模式
    • 原型模式
    • 单例模式
    • 设计模式(2)——工厂方法模式
    • 设计模式(3)——抽象工厂模式
    • 设计模式(4)——模板方法模式
    • 设计模式(5)——代理模式
    • 设计模式(6)——建造者模式
    • 设计模式(7)——策略模式
    • 设计模式(8)——命令模式
    • 设计模式(9)——原型模式
    • 设计模式(10)——中介者模式
    • 设计模式(11)——责任链模式
    • 设计模式(12)——装饰器模式
      • 基本思想和原则
      • 动机
      • 实现
      • 优点
      • 缺点
    • 设计模式(13)——适配器模式
    • 设计模式(14)——迭代器模式
    • 设计模式(15)——观察者模式
    • 设计模式(16)——外观模式
    • 设计模式(17)——状态模式
    • 设计模式(18)——桥接模式
    • 设计模式(19)——享元模式
    • 设计模式(20)——解释器模式
    • 设计模式(21)——组合模式
    • 设计模式(23)——备忘录模式
    • Python 全栈之路系列之单例设计模式
    • 设计模式(22)——访问者模式
    • 工厂方法模式
    • Python 设计模式资源收集
  • 好“艹蛋”的 Python 呀!
  • FIFO | 待学清单📝
  • pip 安装及使用
  • 数据分析

  • 源码阅读计划

  • OOP

  • 关于 python 中的 setup.py
  • 并行分布式框架 Celery
  • 七种武器,让你的代码提高可维护性
  • 使用 pdb 调试 Python 代码
  • 每周一个 Python 标准库
  • 🐍Python
  • 设计模式
佚名
2017-12-13
目录

设计模式(12)——装饰器模式

本文介绍装饰器模式的概念和应用。

# 基本思想和原则

动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式比生成子类更加灵活。

# 动机

我们经常有这样的需求,需要对一个对象进行扩展,一种能直接想到的方案是对原有类派生出多个子类,在子类中实现扩展的功能。这么做是可以,但是缺点也非常明显,继承是一种静态行为,如果我有很多特性需要动态添加到某个对象上,用继承的方式需要派生出非常多的子类,整个类体系臃肿不堪,类数量暴增,到最后根本无法维护。这时候使用装饰器模式可以有效避免这种灾难,装饰器是一种动态的行为,可以动态的增加一些功能到对象上,并且各个装饰器和原来的类耦合很小,扩展起来非常方便。

# 实现

public abstract class Handler {
    public abstract void handle();
}

public class RequestHandler extends Handler {
    @Override
    public void handle() {
        System.out.println("Request processing success.");
    }
}

public abstract class Decorator extends Handler {
    private Handler handler;

    public Decorator(Handler handler) {
        this.handler = handler;
    }

    @Override
    public void handle() {
        this.handler.handle();
    }
}

public class LogDecorator extends Decorator {
    public LogDecorator(Handler handler) {
        super(handler);
    }

    private void log() {
        System.out.println("LogDecorator log.");
    }

    public void handle() {
        super.handle();
        this.log();
    }
}

public class BlacklistDecorator extends Decorator {
    public BlacklistDecorator(Handler handler) {
        super(handler);
    }

    private void filterBlacklist() {
        System.out.println("BlacklistDecorator filter blacklist.");
    }

    public void handle() {
        this.filterBlacklist();
        super.handle();
    }
}

public class Test {
    public static void main(String[] args) {
        Handler requestHandler = new RequestHandler();

        System.out.println("------ Has no decorator ------");
        requestHandler.handle();

        System.out.println();
        System.out.println("------ Add a log decorator ------");
        requestHandler = new LogDecorator(requestHandler);
        requestHandler.handle();

        System.out.println();
        System.out.println("------ Add a blacklist decorator ------");
        requestHandler = new BlacklistDecorator(requestHandler);
        requestHandler.handle();

    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73

输出如下:

------ Has no decorator ------
Request processing success.

------ Add a log decorator ------
Request processing success.
LogDecorator log.

------ Add a blacklist decorator ------
BlacklistDecorator filter blacklist.
Request processing success.
LogDecorator log.
1
2
3
4
5
6
7
8
9
10
11

上面的代码模拟了一个请求被处理的过程,其中RequestHandler类负责实际地处理一个请求,此时我们想在这个基础上增加过滤黑名单和记录日志的功能。使用装饰器模式可以很容易地实现这个功能,装饰器抽象类Decorator可以派生出很多具体的装饰器类,这些装饰器类在内部都维护一个Handler类的实例,装饰器也需要实现Handler类的handle方法,在内部实际上是将具体的处理过程委托给了this.handler去处理,在具体的处理前后增加需要扩展的功能。

BlacklistDecorator装饰器是在请求被处理前进行黑名单检查,LogDecorator装饰器是在请求被处理后进行日志记录。可以看到当在原对象上增加一个装饰器,实际上就是对原对象进行了一层包装,增加几个装饰器就是包装几层。

实际上很多 Web Framework 中的过滤器都是采用装饰器的模式来实现的。

# 优点

装饰器和被装饰的对象相互之间可以独立扩展,耦合度比较低。装饰器模式可以实现对一个对象动态地扩展功能,非常灵活。装饰器模式是比生成子类更轻量级的扩展方式。

# 缺点

要注意对一个对象的装饰层数不要太多,否则调试起来会比较困难。

编辑 (opens new window)
#设计模式
上次更新: 2024-07-23, 01:00:43
设计模式(11)——责任链模式
设计模式(13)——适配器模式

← 设计模式(11)——责任链模式 设计模式(13)——适配器模式→

最近更新
01
2025 面试记录
05-28
02
提升沟通亲和力的实用策略
03-26
03
工作
07-15
更多文章>
Theme by Vdoing | Copyright © 2019-2025 IMOYAO | 别院牧志
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式