当前位置: 代码迷 >> 综合 >> 【设计模式基础】结构型模式 - 3 - 装饰者(Decorator)
  详细解决方案

【设计模式基础】结构型模式 - 3 - 装饰者(Decorator)

热度:19   发布时间:2023-12-14 20:14:08.0

1. 模式意图

动态地给一个对象添加一些额外的职责;Decorator模式相比生成子类更为灵活;(别名Wrapper)

有时候,我们需要为一个对象而不是整个类添加一些新的功能,如果使用继承机制来实现,不同的功能组合将会导致类的爆炸.

2. 模式定义


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

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

Decrator:                         维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。

ConcreteDecratorA/B: 想组件添加职责;


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

3. 模式实现


4. 模式应用

4.1 Java IO

在由InputStream, OutStream, Reader 和 Writter代表的等级结构内部,有一些流处理器可以对另一些流处理器起到装饰作用,形成新的,具有改善了的功能的流处理器。装饰者模式是Java I/O库的整体设计模式:
  • java.io.InputStream (implements java.io.Closeable)
    • java.io.ByteArrayInputStream
    • java.io.FileInputStream
    • java.io.FilterInputStream
      • java.io.BufferedInputStream
      • java.io.DataInputStream (implements java.io.DataInput)
      • java.io.LineNumberInputStream
      • java.io.PushbackInputStream
    • java.io.ObjectInputStream (implements java.io.ObjectInput, java.io.ObjectStreamConstants)
    • java.io.PipedInputStream
    • java.io.SequenceInputStream
    • java.io.StringBufferInputStream
  • java.io.OutputStream (implements java.io.Closeable, java.io.Flushable)
    • java.io.ByteArrayOutputStream
    • java.io.FileOutputStream
    • java.io.FilterOutputStream
      • java.io.BufferedOutputStream
      • java.io.DataOutputStream (implements java.io.DataOutput)
      • java.io.PrintStream (implements java.lang.Appendable, java.io.Closeable)
    • java.io.ObjectOutputStream (implements java.io.ObjectOutput, java.io.ObjectStreamConstants)
    • java.io.PipedOutputStream
  • java.io.Reader (implements java.io.Closeable, java.lang.Readable)
    • java.io.BufferedReader
      • java.io.LineNumberReader
    • java.io.CharArrayReader
    • java.io.FilterReader
      • java.io.PushbackReader
    • java.io.InputStreamReader
      • java.io.FileReader
    • java.io.PipedReader
    • java.io.StringReader
  • java.io.Writer (implements java.lang.Appendable, java.io.Closeable, java.io.Flushable)
    • java.io.BufferedWriter
    • java.io.CharArrayWriter
    • java.io.FilterWriter
    • java.io.OutputStreamWriter
      • java.io.FileWriter
    • java.io.PipedWriter
    • java.io.PrintWriter
    • java.io.StringWriter
例如一下代码:
try
{InputStream in = new DataInputStream(new FileInputStream("test.txt"));
}catch (FileNotFoundException e)
{e.printStackTrace();
}
这是一个典型的Decorator模式的使用, FileOutputStream相当于Component,DataOutputStream就是一个Decorator。
模式图如下:

根据输入流的源的类型,可以将这些流类分成两种,即 原始流类(Original Stream)连接流处理器(Wrapper Stream)
原始流处理器:
原始流处理器接受一个Byte数组对象,String对象,FileDiscriptor对象或者不同类型的流源对象,以InputStream为例,原始流处理器包括以下四种:
ByteArrayIInputStream:为多线程的通信提供缓冲区操作功能,接受一个Byte数组作为流的源;
FileInputStream:建立一个与文件有关的输入流,接受一个File对象作为流的源;
PipedInputStream:可以与PipedOutputStream配合使用,用于读入一个数据管道的数据,接受一个PipedOutputStream作为源;
StringBufferInputStream:将一个字符串缓冲区转换为一个输入流,接受一个String对象作为流的源;

链接流处理器:
所谓链接流处理器,就是可以接受另一个流对象作为源,并对之进行功能扩展的类。InputStream类型的链接处理器包括以下几种,它们都接受另一个InputStream对象作为流源:
FilterInputStream:过滤输入流,它将另一个输入流作为流源,子类包括:
BufferedInputStream:用来从硬盘将数据读入到一个内存缓冲区,并从缓冲区提供数据;
DataInputStream:提供基于多字节的读取方法,可以读取原始类型的数据;
LineNumberInputStream:提供带有行计数功能的过滤输入流;
PushbackInputStream:提供特殊的功能,可以将已经读取的字节推回输入流中;
ObjectInputStream:可以将使用ObjectInputStream串行化的原始数据类型和对象重新并行化;
SequeneInputStream:可以将两个已有的输入流链接起来,形成一个输入流,从而将多个输入流排列构成一个输入流序列;

按照上面的这种原始流处理器和链接流处理器的划分,可以用下面的结构图来描述它们之间的关系:


上面的流处理器图跟装饰者模式的结构图有着显而易见的相同之处。

链接流对象接受一个原始流对象或者另外一个链接流对象作为流源,它们对流源的内部工作方法做了相应的改变,这种改变是装饰者所要达到的目的。 例如:
BufferedInputStream装饰了InputSteam的内部工作方式,使得流的读入操作使用了缓冲机制。在使用了缓冲机制后,不会对每一次的流读入操作都产生一个物理的读盘操作,从而提高了程序的效率,在涉及到物理流的读入时,都应当使用这个装饰流类。