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

装饰器模式使你可以在运行时使用类似于对象组成的技术来装饰类。这在我们希望实例化具有新职责的对象而无需对基础类进行任何代码更改的情况下尤其有用。本文是在学习完优锐课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. 【Linux系列】Centos 7部署Laravel项目(七)

    目的 本文主要介绍以下五点: 一. Composer安装 二. SSH设置 三. Git安装 四. Laravel部署 五. 上传GitHub 演示 一. Composer安装 # cd /usr/l ...

  2. PostGIS 爆管分析之找出总阀门

    这个算法算是被摒弃了,但是很多自己思考过后留下的成果,虽然不用了,留着做记录. 算法目的是为了发生爆管后找到总阀门,这里分了几个步骤: 1.找到爆管点所在管段 2.通过遍历找到爆管点所有影响的阀门 3 ...

  3. C#变量---xdd

    cshape(c#)学习笔记 1. string str1=Console.ReadLine();//键盘输入的默认为字符串 2.  Console.WriteLine('你的成绩是'+a+'分'); ...

  4. SpringBoot系列之集成Thymeleaf用法手册

    目录 1.模板引擎 2.Thymeleaf简介 2.1).Thymeleaf定义 2.2).适用模板 3.重要知识点 3.1).th:text和th:utext 3.2).标准表达式 3.3).Thy ...

  5. es6 every的使用

    let arr2 =[1,3,5,7,9,10]; //arr2.every() 数组里面所有的元素都有符合条件,才返回true var b =arr2.every(function (val,ind ...

  6. ctf中关于图片的隐写随笔(不全)

    ①JPG图片的结束符,十六进制常为FFD9 ②binwalk的原理是:检查常见的文件头信息,如果不符合,一定有隐藏信息.③JPG是有损压缩,PNG是无损压缩,BMP是不压缩. 隐写的基本原理:图片查看 ...

  7. python中的random模块简析

    在Python生成随机数用random模块,下面的文章是本人自己简单总结的ython生成随机数与random模块中最常用的几个函数的关系,希望对大家有所帮助. random.random()用于生成随 ...

  8. 三分钟带你入门 redis 高可用架构之哨兵

    什么是哨兵? 哨兵(Sentinel)是 redis 的高可用性解决方案,前面我们讲的主从复制它是高可用的基础,需要人工介入才能完成故障转移,哨兵可以解决这个问题,在主从复制情况下,当主节点发生故障时 ...

  9. Chapter 07-Basic statistics(Part3 correlations)

    这一部分使用R基础已安装包中的state.x77数据集.该数据集的数据是关于美国50个州在1977年对人口,收入,文盲率,平均寿命,谋杀率,高中毕业率统计所得. 1.关联的种类(types of co ...

  10. (Nginx+PHP+MySQL)单机+Redis部署

    链接:Nginx+PHP+MySQL+Redis多机部署 1.lnmp+redis工作机制 2.lnmp+redis操作步骤(lnmp为单机部署) (1)lnmp+redis实战环境 lnmp服务器: ...