抽丝剥茧 细说架构那些事——【优锐课】

装饰器模式使你可以在运行时使用类似于对象组成的技术来装饰类。这在我们希望实例化具有新职责的对象而无需对基础类进行任何代码更改的情况下尤其有用。本文是在学习完优锐课JAVA架构VIP课程—【框架源码专题】中《学习源码中的优秀设计模式》后写下的学习感悟。探讨了这种模式,并向你展示了如何使用提供的Java代码示例来实现它。

深入探索Java设计模式(一)之单例模式

深入探索Java设计模式(二)之策略模式

总览

装饰器模式是“四人帮”(Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides)建立的结构设计模式之一。 通过解决在运行时向对象添加新状态或行为的反复出现的问题,它在面向对象的设计中利用了可重用性和灵活性。尽管这种想法与面向对象原理(称为继承)押韵,但简单继承在这种情况下不适用,因为它是静态的并且考虑到整个类。这为新方法铺平了道路,因为它着重于提供灵活的替代方法来扩展子类功能,因此可以动态地向对象施加新的责任。

装饰器模式

顾名思义,装饰器模式可配置特定对象的功能。这是Java原始IO类中的一种常见模式,用于对JVM之外的源进行读写。例如,InputStream和OutputStream类及其子类在其读取和写入操作中广泛使用此模式。可以链接这些类的实现,以有效地从不同的源(例如本机文件系统)读取和写入数据。

例如,请注意抽象类OutputStream。它有一个称为read的抽象方法,该方法必须由子类定义。可以重写该方法以扩展其行为,以更改或增强其效率。在将职责委派给另一个OutputStream之前,OutputStream实现会执行所需的工作。实现链将另一个OutputStream用作构造函数参数。具体的子类,例如OutputStream的FileOutputStream或SocketOutputStream,是管道的末尾,最终写入数据,而没有将写入责任委托给另一个流。因此,在其构造函数参数中不需要另一个OutputStream对象。

让我们看看在Java IO类的OutputStream类中使用装饰器模式如何导致在将字节数组写入磁盘之前将多个操作链接在一起。

 @Test
public void testingDecoratorPattern() throws IOException {
final File file = new File("myfile.dat");
final FileOutputStream fileOutputStream = new
FileOutputStream(f);
final BufferedOutputStream bufferedOutputStream = new
BufferedOutputStream(fileOutputStream);
final ObjectOutputStream objectOutputStream = new
ObjectOutputStream(fileOutputStream);
objectOutputStream.writeBoolean(true);
objectOutputStream.writeInt(12);
objectOutputStream.writeObject(new ArrayList<Integer>());
objectOutputStream.flush();
objectOutputStream.close();
bufferedOutputStream.close();
fileOutputStream.close();
assertTrue(file.exists());
}

FileOutputStream对象用于将文件写入磁盘。 BufferedOutputStream对象缓存对写操作的所有调用,并一次写入几个字节。 这可以提高效率,特别是在写入磁盘时。ObjectOutputStream中的对象序列化的内置机制将对象和原始类型写入流中。但是,ObjectOutputStream不知道将文件写入何处。这主要用于将责任委托给另一个OutputStream。

装饰器模式的使用

假设我们要创建一个类设计,但要增加新功能。 在这种情况下,装饰器模式可为客户端提供所需的功能组合,以增强进一步的实现,如图1所示。

1:装饰器模式

在这里,茶是一个抽象类,由产品的所有类别或变体子类化。在包含有关其类型的特定信息的每个子类中都设置了detailsinstance变量。getDetails()方法返回有关其类型的信息。父类将price() 方法声明为抽象,子类将定义其自己的实现。除了可用的茶类型以外,我们还可以通过多种变体和组合实现任意数量的茶。这是装饰器模式的关键。

实现装饰器模式

现在,让我们看看如何实现装饰器模式。该示例非常简单,不言自明。这些类的布局如下。

 package org.mano.example;
public interface Car {
void paint();
} package org.mano.example;
public class ElectricCar implements Car {
@Override
public void paint() {
// ...
}
} package org.mano.example;
public class HybridCar implements Car {
@Override
public void paint() {
// ...
}
} package org.mano.example;
public abstract class CarDecorator implements Car {
protected Car decoratedCar;
public CarDecorator(Car car){
decoratedCar = car;
}
public void paint(){
decoratedCar.paint();
}
} package org.mano.example;
public class CarColorDecorator extends CarDecorator {
public CarColorDecorator(Car car) {
super (car);
}
@Override
public void paint(){
decoratedCar.paint();
setTheme(decoratedCar);
}
private void setTheme(Car car){
// ...
} } package org.mano.example;
public class DPApp {
public static void main(String[] args) {
Car defaultHybridCar = new HybridCar();
Car redHybridCar = new CarColorDecorator(new
HybridCar());
Car blueElectricCar = new CarColorDecorator(new
ElectricCar());
defaultHybridCar.paint();
redHybridCar.paint();
blueElectricCar.paint();
}
}

结论

这是OOP中最常用的模式之一。这种模式的强大之处在于将对象组合在一起,例如ObjectOutputStream,BufferedOutputStream和FileOutputStream扩展了抽象超类OutputStream。每个子类构造函数都将OutputStream对象作为参数。没有装饰器模式,这将是不可能的。否则,我们必须创建许多类来获取本质,这将是一个糟糕的设计。

感谢阅读!欢迎留言。想更深入探讨学习也欢迎私信我。下篇继续~

深入探索Java设计模式(四)之享元模式

深入探索Java设计模式(五)之构建器模式

深入探索Java设计模式(三)之装饰器模式的更多相关文章

  1. 重学 Java 设计模式:实战装饰器模式(SSO单点登录功能扩展,增加拦截用户访问方法范围场景)

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 对于代码你有编程感觉吗 很多人写代码往往是没有编程感觉的,也就是除了可以把功能按照固 ...

  2. Java设计模式12:装饰器模式

    装饰器模式 装饰器模式又称为包装(Wrapper)模式.装饰器模式以多客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰器模式的结构 通常给对象添加功能,要么直接修改对象添加相应的功能, ...

  3. JAVA设计模式之【装饰者模式】

    JAVA设计模式之[装饰者模式] 装饰模式 对新房进行装修并没有改变房屋的本质,但它可以让房子变得更漂亮.更温馨.更实用. 在软件设计中,对已有对象(新房)的功能进行扩展(装修). 把通用功能封装在装 ...

  4. 设计模式PHP篇(三)————装饰器模式

    简单的用php实现了装饰器模式: <?php /** *简单的装饰器模式 */ class PrintText { protected $decorators = []; public func ...

  5. 设计模式(三)——装饰器模式(Decorator Pattern)

    发现太过于刻意按照计划来写博客,有点不实际,刚好最近在一个网课上复习AOP的知识,讲到了装饰器模式和代理模式,顺便复习总结一下. 首先了解一下装饰器模式,从名字里面可以看出来,装饰器模式就类似于房子装 ...

  6. Java IO流以及装饰器模式在其上的运用

    流概述 Java中,流是一种有序的字节序列,可以有任意的长度.从应用流向目的地称为输出流,从目的地流向应用称为输入流. Java的流族谱 Java的 java.io 包中囊括了整个流的家族,输出流和输 ...

  7. 设计模式学习心得<装饰器模式 Decorator>

    装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包装 ...

  8. 设计模式のDecoratorPattern(装饰器模式)----结构模式

    一.产生背景 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装 ...

  9. 设计模式入门之装饰器模式Decorator

    //装饰模式定义:动态地给一个对象加入一些额外的职责. //就添加功能来说.装饰模式比生成子类更为灵活 //这也提现了面向对象设计中的一条基本原则,即:尽量使用对象组合,而不是对象继承 //Compo ...

  10. java进阶系列之装饰器模式

    1.介绍 装饰器模式顾名思义就是装饰某个对象的,是一种结构型模式.装饰器模式允许向一个现有对象添加新的功能,同时不改变其结构,用户可以随意的扩展原有的对象.它是作为现有的类的一个包装.装饰器模式一方面 ...

随机推荐

  1. rhel-6.3-i386安装samba

    1.安装samba 1).安装软件 rpm –ivh /mnt/Packages/samba-3.5.10-125.el6.i686.rpm 2).创建用户 useradd myadmin 3).设置 ...

  2. Oracle '26-2月 -19 03.34.47.000000 下午' 字符串日期解析

    Oracle数据库, 时间字段是varchar2类型, 存储了 '26-2月 -19 03.34.47.000000 下午' 格式(TIMESTAMP 数据类型)的字符串日期, 将其解析为yyyy-M ...

  3. ceph中rbd的增量备份和恢复

    ceph中rbd的增量备份和恢复 ceph的文档地址:Ceph Documentation ​ 在调研OpenStack中虚机的备份和恢复时,发现OpenStack和ceph紧密结合,使用ceph做O ...

  4. 20191017-3 alpha week 2/2 Scrum立会报告+燃尽图 02

    此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/9799 一.小组情况 队名:扛把子 组长:迟俊文 组员:宋晓丽 梁梦瑶 韩昊 ...

  5. 20191010-3 alpha week 1/2 Scrum立会报告+燃尽图 01

    此作业要求参见https://edu.cnblogs.com/campus/nenu/2019fall/homework/8746 一.小组情况 组长:迟俊文 组员:宋晓丽 梁梦瑶 韩昊 刘信鹏 队名 ...

  6. scrapy抓取斗鱼APP主播信息

    如何进行APP抓包 首先确保手机和电脑连接的是同一个局域网(通过路由器转发的网络,校园网好像还有些问题). 1.安装抓包工具Fiddler,并进行配置 Tools>>options> ...

  7. JPA-@MappedSuperclass

    今天阅读前辈的代码时,发现一个新的注解 @MappedSuperclass ,下面就来了解下它是干什么的: 首先官方文档给出的解释是: Designates a class whose mapping ...

  8. Knative Serverless 之道:如何 0 运维、低成本实现应用托管?

    作者 | 牛秋霖(冬岛)  阿里云容器平台技术专家 关注"阿里巴巴云原生"公众号,回复关键词"1205"即可观看 Knative-Demo 演示视频. 导读:S ...

  9. c语言I博客专业06

    问题 答案 这个作业属于那个课程 C语言程序设计II 这个作业要求在哪里 https://edu.cnblogs.com/campus/zswxy/CST2019-2/homework/8655 我在 ...

  10. 构建一个flink程序,从kafka读取然后写入MYSQL

    最近flink已经变得比较流行了,所以大家要了解flink并且使用flink.现在最流行的实时计算应该就是flink了,它具有了流计算和批处理功能.它可以处理有界数据和无界数据,也就是可以处理永远生产 ...