本文实例代码:github.com/JamesZBL/ja…

装饰器(Decorator)模式用于动态地给一个对象添加一些额外的职责。 就增加功能来说, Decorator模式相比生成子类更为灵活。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

纯粹的装饰模式很难找到,大多数的装饰模式的实现都是“半透明”的,而不是完全透明的。换言之,允许装饰模式改变接口,增加新的方法。半透明的装饰模式是介于装饰模式和适配器模式之间的。适配器模式的用意是改变所考虑的类的接口,也可以通过改写一个或几个方法,或增加新的方法来增强或改变所考虑的类的功能。 大多数的装饰模式实际上是半透明的装饰模式,这样的装饰模式也称做半装饰、半适配器模式。

适用场景

以下情况使用Decorator模式

  • 在不影响其他对象的情况下, 以动态、 透明的方式给单个对象添加职责。

  • 处理那些可以撤消的职责。

  • 当不能采用生成子类的方法进行扩充时。 一种情况是, 可能有大量独立的扩展, 为支持每一种组合将产生大量的子类, 使得子类数目呈爆炸性增长。 另一种情况可能是因为类定义被隐藏, 或类定义不能用于生成子类。

模式要点

组成部分

  • Component:定义一个对象接口, 可以给这些对象动态地添加职责。

  • ConcreteComponent:定义一个对象, 可以给这个对象添加一些职责。

  • Decorator:持有一个指向 Component 对象的引用,并定义一个与 Component 接口一致的接口。

  • ConcreteDecorator:一向组件添加职责。

协作原理

  • Decorator 将请求转发给它的 Component 对象, 并有可能在转发请求前后执行一些附加的动作。

实例分析

[站外图片上传中...(image-a0ad13-1526278884853)]

铁匠和木匠同时制作一把铁锤,第一种方案是木匠制作锤把,铁匠制作锤头;第二中方案是铁匠先制作锤把再制作锤头(假定这里的木匠只会制作锤把)。制作过程分为三部分:1.对材料进行初步的检查,2.进行制造并把部件安装起来以供后面的操作,3.完成之后再次进行检查,确保没有质量问题。

首先定义“操作”接口,包括前后两次检查以及安装的操作。


/*** 流水线上操作行为的接口*/public interface Operation {void checkBefore();void join();void chekcAfter();}复制代码

现在只由木匠制作锤把,定义一个木匠的操作类 CarpenterOperation


/*** 木匠的工作*/public class CarpenterOperation implements Operation {private static final Logger LOGGER = LoggerFactory.getLogger(CarpenterOperation.class);@Overridepublic void checkBefore() {LOGGER.info("检查木材");}@Overridepublic void join() {LOGGER.info("打造锤把");}@Overridepublic void chekcAfter() {LOGGER.info("检查成品锤把");}}复制代码

由于某些原因,铁匠决定自己制作锤把,现在铁匠身兼双职,将木匠的工作也承担了。定义一个铁匠操作类 HammerSmith


/*** 铁匠*/public class HammerSmithOperation implements Operation {private static final Logger LOGGER = LoggerFactory.getLogger(HammerSmithOperation.class);private Operation previousOperation;public HammerSmithOperation(Operation previousOperation) {this.previousOperation = previousOperation;}@Overridepublic void checkBefore() {previousOperation.checkBefore();LOGGER.info("检查铁材");}@Overridepublic void join() {previousOperation.join();LOGGER.info("打造锤头");}@Overridepublic void chekcAfter() {previousOperation.chekcAfter();LOGGER.info("检查成品锤头");}}复制代码

同样实现了“操作”的接口,铁匠的每个操作都包含了木匠相应的操作,相当于对木匠的操作增加了一层包裹和扩展。这种包装就是 Decorator 模式中的装饰。

现在分别让木匠和铁匠进行一系列操作


/*** Decorator*/public class Application {private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);public static void main(String[] args) {LOGGER.info("仅由木匠制作锤把");Operation carpenter = new CarpenterOperation();carpenter.checkBefore();carpenter.join();carpenter.chekcAfter();LOGGER.info("由铁匠完成锤把以及锤头的制作");Operation hammerSmith = new HammerSmithOperation(carpenter);hammerSmith.checkBefore();hammerSmith.join();hammerSmith.chekcAfter();}}复制代码

输出如下内容

仅由木匠制作锤把检查木材打造锤把检查成品锤把由铁匠完成锤把以及锤头的制作检查木材检查铁材打造锤把打造锤头检查成品锤把检查成品锤头复制代码

效果

优点

1. 装饰模式和静态继承的机制的作用都是对现有的类增加新的功能,但装饰模式有着比静态继承更灵活的组合方式。装饰模式可以在运行的时候决定需要增加还是去除一种“装饰”以及什么“装饰”。静态继承则没有这样的灵活性,它对类功能的扩展是在运行之前就确定了的。

2. 得益于装饰模式在组合上的灵活性和便利性,我们可以将各种装饰类进行组合,从而较为简单的创造各种不同的行为集合,实现多种多样的功能。

缺点

1. 装饰者的对象和它装饰的对象本质上是完全不同的,装饰模式会生成许多的对象,导致区分各种对象变得困难

2. 由于使用相同的标识,对于程序的理解和排错过程的难度也会随之增加

个人博客同步更新,获取更多技术分享请关注:郑保乐的博客

设计模式学习笔记(3)装饰器相关推荐

  1. 研磨设计模式学习笔记之装饰器模式

    1.装饰器模式定义:动态地给一个对象添加一些额外的功能职责,就增加功能来说,装饰器模式要比生成子类更加灵活. 2.装饰器模式实现:在装饰器模式的实现中,为了能够实现和原来使用被装饰对象的代码无缝隙结合 ...

  2. [转载] Python学习笔记——用装饰器decorator和Memoization记忆化提高效率,原理讲清楚了

    参考链接: 在Python中使用装饰器进行记忆 Python学习笔记--用装饰器decorator和Memoization记忆化提高效率 装饰器Memoization记忆化运用`functools`中 ...

  3. Python学习笔记:装饰器

    前言 最近在学习深度学习,已经跑出了几个模型,但Pyhton的基础不够扎实,因此,开始补习Python了,大家都推荐廖雪峰的课程,因此,开始了学习,但光学有没有用,还要和大家讨论一下,因此,写下这些帖 ...

  4. python学习笔记(装饰器、迭代器生成器、内置函数、软件目录开发规范)

    装饰器 定义:本质是函数,(功能:装饰其他函数):就是为其他函数添加附加功能 模拟场景一,在现有的函数中增加某个功能.现有的做法是定义新函数,并且加入函数中.需要修改源代码. def logger() ...

  5. python学习笔记之装饰器、递归、算法(第四天)

    参考老师的博客: 金角:http://www.cnblogs.com/alex3714/articles/5161349.html 银角:http://www.cnblogs.com/wupeiqi/ ...

  6. python文件下载速度 装饰器_python学习笔记之---装饰器

    # -*- coding:utf-8 -*- '''示例1: 最简单的函数,表示调用了两次''' def myfunc(): print ("myfunc() called.") ...

  7. python装饰器详解-学习笔记-Python装饰器详解

    1.什么是装饰器 装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就不能大批量的修改源代码,这样是不科学的也是不现实的,因为就产生了装饰器,使得其满足: 不能修改被装饰的函数的 ...

  8. [转载] python学习笔记——@property装饰器

    参考链接: Python @property装饰器 上篇:https://blog.csdn.net/qq_42489308/article/details/89423412 @property装饰器 ...

  9. python学习笔记之——装饰器及对象

    1.反射之__import__ 我们知道import语句是用来导入外部模块的,当然还有from...import...也可以,但是其实import实际上是使用builtin函数__import__来工 ...

  10. 设计模式学习笔记之装饰者模式

    装饰者模式     动态的将责任附加到对象上.若要扩展功能,装饰者模式提供了比继承更有弹性的替代方案. 说明: 1.装饰者和被装饰者对象有相同的超类型: 2.可以用一个或者多个装饰者包装一个对象: 3 ...

最新文章

  1. 直播 | ICML 2021论文解读:具有局部和全局结构的自监督图表征学习
  2. 视图中的难点:主键表 About Key-Preserved Tables
  3. python中分割字符串两种方法正则分组别名,如何在python中使用正则表达式模块将文本字符串分割成单词?...
  4. selenium--特殊元素定位
  5. 【重点】剑指offer——面试题27:二叉搜索树与双向链表
  6. 分享一个selenium jar包 的下载地址,各版本都有,包括selenium-server-standalone.jar、selenium、selenium-server
  7. Nginx使用GeoIP模块来限制地区访问
  8. C语言栈括号匹配算法
  9. 超详细用实验教你如何配置OSPF
  10. JAVA实现UDP单播组播
  11. 西雅图华盛顿大学计算机专业录取,华盛顿大学西雅图分校录取
  12. CISSP备考大全(完整版)
  13. 云服务器初始化失败怎么办,提示交互式登录进程初始化失败是什么原因?解决方法步骤教程...
  14. 小功能⭐️Unity动态更改 Scripting Define Symbols (宏定义)
  15. 下一代防火墙(NGFW)已死!
  16. spark+smack+openfire实现请求响应简单流程
  17. R 回归分析 逐步回归
  18. 旅行时,如何通过树莓派和iPad Pro备份图片
  19. 被关注的独山县:400亿数字背后是什么? | Alfred数据室
  20. js 针对异步的处理

热门文章

  1. python里我最容易搞不清楚问题之一的encode和decode
  2. Dockerfile制作自定义镜像
  3. 校赛热身 Problem C. Sometimes Naive (状压dp)
  4. DevExpress 创建EXCEL
  5. iScroll API
  6. Linux多任务编程(二)---fork()函数及其基础实验
  7. x201 温度过高 反应慢 硬盘搜索时更慢更热 为什么呢?
  8. 窗口封装类与Windows窗口实例的关系-3、CWnd如何处理窗口消息
  9. 数据结构上机实践第10周项目1 - 二叉树算法验证
  10. YOLO系列专题——Complex-YOLO