当前位置: 首页 > news >正文

《java与模式》学习系列——装饰模式

 

一、 装饰(Decorator)模式的结构

装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

装饰模式有透明和半透明的两种,这两种的区别就在于装饰角色的接口与抽象构件角色的接口是完全一致。半透明情况下装饰角色的接口比抽象构件角色的接口宽。

所下图所示:

如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把DecoratorConcreteDecorator的责任合并成一个类。

二、 装饰模式适用的场景

1、需要扩展一个类的功能,或给一个类增加附加责任。

2、需要动态地给一个对象增加功能,这些功能可以再动态地撤销。

3、需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

装饰模式的优点:

1、装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。

2、通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。

三、 工厂方法与其他模式的关系

适配器模式

装饰模式和适配模式都是包装(Wrapper)模式。适配器模式的用意是要改变所考虑的对象的接口而不一定改变对象的性能,而装饰模式的用意是要保持接口,从而增加所考虑对象的性能。

策略模式

装饰模式将一个东西的表皮换掉,而保持它的内心。策略模式恰好相反,它在保持接口不变的情况下,使具体算法可以互换。

装饰模式的实现要求Component类尽量地“轻”,而策略模式要求抽象策略类尽量的“重”。

合成模式

装饰模式常常用在合成模式的行为扩展上。使用继承关系扩展合成模式的行为很困难。装饰模式是继承关系的替代方案,装饰模式可以动态地为合成模式添加新的行为。

四、装饰模式在java中的应用

         java I/O

java I/O库的两个对称性和两个设计模式

两个对称性

1、输出—输入对称:比如InputStreamOutputStream各自占据Byte流的输入与输出的两个平行结构的根部:而ReaderWriter各自占据Char流的输入与输出的两个平行的等级结构的根部。

2bytechar对称:InputStreamReader的子类分别负责ByteChar流的输入;OutputStreamWriter的子类分别负责ByteChar流的输出,它们分别形成平行的等级结构。

两个设计模式

1、装饰模式:在由InputStreamOutputStreamReaderWriter代表的等级结构内部,有一些流处理器可以对另一流处理器起到装饰作用,形成新的、具有改善了的功能的流处理器。

2、在由InputStreamOutputStreamReaderWriter代表的等级结构内部,有一些流处理器是对其他类型的流源的适配。这就是适配器模式的应用。

 

InputStream中的装饰模式:

InputStream类型中的装饰模式是半透明的,换言之,链接流处理器在对源流处理器进行功能增强的同时,改变了源流处理器的接口。例如:BufferedInputStream是一个半透明的装饰类,因为他提供了额外的方法ensureOpen()fill(),如果客户端持有一个类型为InputStream的对象引用in的话,那么如果用BufferedInputStream装饰后,只要客户端不需要使用像ensureOpen以及fill方法,客户端就没有问题。但是如果客户端必须使用这两个方法,那必须进行向下类型转换,那么这个类型转换意味着客户端必须知道它拿到的引用是指向一个类型为BufferedInputStream的对象的,这就破坏了使用装饰的原始用意:不让客户端察觉它使用的仅是一个装饰,而不是原始流角色。

Reader类型的装饰模式:

 

InputStream中的适配器模式:

ByteArrayInputStream继承了InputStream的接口,而封装了一个byte数组。换言之,它将一个byte数组的接口适配成InputStream流处理器的接口。

StringBufferInputStream继承了InputStream类型,同时持有一个对String对象的引用。这是一个将String对象适配成InputStream类型的对象形式的适配器模式

byte流到char流的适配:

InputStreamReader是从byte输入流到chr输入流的一个适配器

OutputStreamWriter是从byte输出流到char输出流的一个适配器。

 

相关文章:

  • 初始化Git的配置
  • 《java与模式》学习系列——享元模式
  • Java WebService 简单实例
  • java.lang.instrument使用
  • 《java与模式》学习系列——门面模式
  • 《java与模式》学习系列——桥梁模式
  • 《java与模式》学习系列——观察者模式
  • angularjs服务-service
  • 《java与模式》学习系列——迭代子模式
  • Werkzeug工具包学习-官方例子Shortly分析
  • 《java与模式》学习系列——责任链模式
  • iOS中的交换空间(swap space)
  • 《java与模式》学习系列——命令模式
  • Windows10中无法打开这个应用的解决方案
  • sqlbulkcopy 使用DataTable作为数据源的数据类型问题--来自数据源的String类型的给定值不能转换为指定目标列的类型 uniqueidentifier...
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • ESLint简单操作
  • JavaScript的使用你知道几种?(上)
  • Quartz初级教程
  • RxJS: 简单入门
  • Swift 中的尾递归和蹦床
  • 当SetTimeout遇到了字符串
  • 简单实现一个textarea自适应高度
  • 将 Measurements 和 Units 应用到物理学
  • 如何打造100亿SDK累计覆盖量的大数据系统
  • 三栏布局总结
  • 王永庆:技术创新改变教育未来
  • 一些css基础学习笔记
  • hi-nginx-1.3.4编译安装
  • ​secrets --- 生成管理密码的安全随机数​
  • # MySQL server 层和存储引擎层是怎么交互数据的?
  • #QT(串口助手-界面)
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (11)MSP430F5529 定时器B
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (3)(3.5) 遥测无线电区域条例
  • (C#)一个最简单的链表类
  • (C语言)深入理解指针2之野指针与传值与传址与assert断言
  • (DFS + 剪枝)【洛谷P1731】 [NOI1999] 生日蛋糕
  • (libusb) usb口自动刷新
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (强烈推荐)移动端音视频从零到上手(下)
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (区间dp) (经典例题) 石子合并
  • (四)Linux Shell编程——输入输出重定向
  • (转载)Linux网络编程入门
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .net流程开发平台的一些难点(1)
  • .NET项目中存在多个web.config文件时的加载顺序
  • @manytomany 保存后数据被删除_[Windows] 数据恢复软件RStudio v8.14.179675 便携特别版...
  • [ JavaScript ] JSON方法
  • [ vulhub漏洞复现篇 ] Apache Flink目录遍历(CVE-2020-17519)
  • [acwing周赛复盘] 第 69 场周赛20220917
  • [AIGC] Nacos:一个简单 yet powerful 的配置中心和服务注册中心