把书读薄 | 《设计模式之美》设计模式与范式(结构型-装饰器模式)(下)

简介: 本文对应设计模式与范式:结构型(50),装饰器模式 (Decorator Pattern)。装饰器模式和上节学的**桥接模式**(分离实体和行为) 代码结构非常相似,都是用组合来扩展原有类,但解决的问题大不相同。Tips:二手知识加工难免有所纰漏,感兴趣有时间的可自行查阅原文,谢谢。

四个角色:


  • Component (抽象组件) → 声明具体组件实现的业务方法,让客户端以一致的方式处理为修饰和修饰后的对象;


  • ConcreteComponent (具体组件) → 抽象组件的具体实现;


  • Decorator (抽象装饰类) → 包含对组件的引用,并重写抽象组件的方法;


  • ConcreteDecorator (具体装饰类) → 抽象装饰类的具体实现,除了重写方法外,还可以添加附加功能;


适用场景:


  • 在不影响其他对象的情况下,快速动态透明地为单个对象添加功能;


  • 不支持继承扩展类的场景,如final关键字修饰的类;


优点


快速扩展对象功能,比继承灵活,不会导致类个数急剧增加,动态增删对象实例功能,按需按顺序组合功能;


缺点


  • 顺序调用链装饰时,删除某个装饰器需要修改上下文代码;


  • 容易增加很多装饰对象,增加代理理解难度;


  • 和桥接模式一样,组合相比继承,更不容易找到对象间的调用关系;


附:装饰器模式应用示例 → Java IO类库


在网上找了张Java IO的继承树形图:


网络异常,图片无法展示
|


两个变化维度:字节流 or 字符流输入流 or 输出流,组合出四个子类:

InputStreamOutputStreamReaderWriter,针对不同的读写场景,从这四个父类的基础上,又扩充出很多子类。


在日常使用时,又涉及到了一个 低级流高级流 的概念,高级流不能直接使用,需要传入低级流,裹好几层,如:


InputStream in = new FileInputStream("/user/jie/test.txt");
InputStream bin = new BufferedInputStream(in);
DataInputStream din = new DataInputStream(bin);
int data = din.readInt();


原理就是采用了装饰器模式,低级流可以按需进行功能增强,如上面的支持缓存,支持按照基本类型读取数据。可以打开这三个类看看:


网络异常,图片无法展示
|


可以看到,都继承了InputStream类,中间两个类的构造函数传递的InputStream的实例:


网络异常,图片无法展示
|


看下DataInputStream.readInt()方法:


网络异常,图片无法展示
|


int是4个字节,所以这里读了4次,而代码中传入的in是BufferedInputStream的,会调它的read()方法:


网络异常,图片无法展示
|


fill()填充缓冲区,最后返回一个字节数组。


另外,不知道眼尖的你有没有发现,这两个类不是直接继承InputStream,而是继承自FilterInputStream,这样做的原因是:


有些装饰器本身不需要真正处理read()等方法,但是装饰器模式的 链式传递,不用到也要实现这些方法。而每个这样的装饰器都重写方法的话,会存在大量重复代码。用一个装饰器父类FilterInputStream提供默认实现,以此减少这些重复代码。


相关文章
|
1月前
|
设计模式 XML Java
【设计模式】装饰器模式(定义 | 特点 | Demo入门讲解)
【设计模式】装饰器模式(定义 | 特点 | Demo入门讲解)
29 0
|
6月前
|
设计模式 Java
Java一分钟之-设计模式:装饰器模式与代理模式
【5月更文挑战第17天】本文探讨了装饰器模式和代理模式,两者都是在不改变原有对象基础上添加新功能。装饰器模式用于动态扩展对象功能,但过度使用可能导致类数量过多;代理模式用于控制对象访问,可能引入额外性能开销。文中通过 Java 代码示例展示了两种模式的实现。理解并恰当运用这些模式能提升代码的可扩展性和可维护性。
63 1
|
2月前
|
设计模式 Java
Java设计模式-装饰器模式(10)
Java设计模式-装饰器模式(10)
|
5月前
|
设计模式 Java
Java设计模式:深入装饰器模式的三种写法(六)
Java设计模式:深入装饰器模式的三种写法(六)
|
5月前
|
设计模式 程序员
结构型设计模式之适配器模式
结构型设计模式之适配器模式
|
5月前
|
设计模式
结构型设计模式之装饰模式
结构型设计模式之装饰模式
|
5月前
|
设计模式 编解码 网络安全
结构型设计模式之代理模式
结构型设计模式之代理模式
|
5月前
|
设计模式 架构师 安全
设计模式第五讲-装饰器模式和代理模式详解
远程代理,这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如,用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问虚拟硬盘时实际访问的是网盘空间。
264 0
|
15天前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
2月前
|
设计模式 数据库连接 PHP
PHP中的设计模式:提升代码的可维护性与扩展性在软件开发过程中,设计模式是开发者们经常用到的工具之一。它们提供了经过验证的解决方案,可以帮助我们解决常见的软件设计问题。本文将介绍PHP中常用的设计模式,以及如何利用这些模式来提高代码的可维护性和扩展性。我们将从基础的设计模式入手,逐步深入到更复杂的应用场景。通过实际案例分析,读者可以更好地理解如何在PHP开发中应用这些设计模式,从而写出更加高效、灵活和易于维护的代码。
本文探讨了PHP中常用的设计模式及其在实际项目中的应用。内容涵盖设计模式的基本概念、分类和具体使用场景,重点介绍了单例模式、工厂模式和观察者模式等常见模式。通过具体的代码示例,展示了如何在PHP项目中有效利用设计模式来提升代码的可维护性和扩展性。文章还讨论了设计模式的选择原则和注意事项,帮助开发者在不同情境下做出最佳决策。