http://hxraid.iteye.com/blog/432658
继承是OOP程序设计的一大特点,但其实对于很多复杂问题来说,利用继承关系处理问题往往具有很高的耦合性,不利于代码的维护。利用组合很大程度上可以做到降耦。多用组合,少用继承是OOP设计的重要思想。
装饰者模式给我们提出了一个好的OOP设计原则:类应该对扩展开放,对修改关闭 。
这句话的意思就是,如果问题发生改变,衡量一个好的设计标准就是:你不需要修改类中的代码,只需要扩展新类来适应新的行为。
《Head First Design Patterns》对装饰者模式说的很清楚。这里稍微注意几点:
(1) 装饰者和被装饰者必须具有相同的超类型。
(2) 装饰者即可以包装被装饰者,也可以包装装饰者。往往利用多层包装来达到目的。
(3) 装饰者中组合了被装饰者对象,这是装饰类的关键特征。正是由于这种组合,使得我们能够随心所欲的通过嵌套装饰来动态扩展行为。
在java类库中的IO流就是用装饰者模式设计的。JDK5.0中60多个IO流类组成了四大家族:InputStream,OutputStream,Reader,Writer。
InputStream/OutputStream是对字节序列进行操作的抽象类。
Reader/Writer是基于Unicode代码单元进行操作的抽象类。
这四大家族中大量的类都具有自己不同的功能,要做到方便的完成各种输入输出行为。必须组合使用这些类,装饰者模式是再好不过的设计了。那么IO类库如何实现装饰者模式的,我们看看几个类的部分源码:
Java代码
//InputStream:字节序列输入类鼻祖
public abstract class InputStream implements Closeable {
//最基本的读取字节的抽象方法,供子类扩展。
public abstract int read() throws IOException;
}
//InputStream:字节序列输入类鼻祖
public abstract class InputStream implements Closeable {
//最基本的读取字节的抽象方法,供子类扩展。
public abstract int read() throws IOException;
}
Java代码
//FileInputStream: 读取文件中的字节流类 继承InputStream
public class FileInputStream extends InputStream{
//构造器
public FileInputStream(String name) throws FileNotFoundException {
//.......
}
//本地方法,与操作系统低层交互的具体读入方法
public native int read() throws IOException;
}
//FileInputStream: 读取文件中的字节流类 继承InputStream
public class FileInputStream extends InputStream{
//构造器
public FileInputStream(String name) throws FileNotFoundException {
//.......
}
//本地方法,与操作系统低层交互的具体读入方法
public native int read() throws IOException;
}
Java代码
//FilterInputStream: 过滤流类,起装饰器作用,用于对输入装配各种功能
public class FilterInputStream extends InputStream {
//用于记录被装饰者,也就是需要装配新功能的InputStream对象
protected volatile InputStream in;
//构造装饰器
protected FilterInputStream(InputStream in) {
this.in = in; //设置需要被包装InputStream对象
}
//读入字节
public int read() throws IOException {
return in.read();
}
}
//FilterInputStream: 过滤流类,起装饰器作用,用于对输入装配各种功能
public class FilterInputStream extends InputStream {
//用于记录被装饰者,也就是需要装配新功能的InputStream对象
protected volatile InputStream in;
//构造装饰器
protected FilterInputStream(InputStream in) {
this.in = in; //设置需要被包装InputStream对象
}
//读入字节
public int read() throws IOException {
return in.read();
}
}
Java代码
//BufferedInputStream: 使输入流具有缓冲功能,是一种可以装配缓冲功能的装饰器,继承FilterInputStream
public class BufferedInputStream extends FilterInputStream {
//构造器
public BufferedInputStream(InputStream in) {
this(in, defaultBufferSize); //in就是被装配缓冲功能的InputStream
}
}
//BufferedInputStream: 使输入流具有缓冲功能,是一种可以装配缓冲功能的装饰器,继承FilterInputStream
public class BufferedInputStream extends FilterInputStream {
//构造器
public BufferedInputStream(InputStream in) {
this(in, defaultBufferSize); //in就是被装配缓冲功能的InputStream
}
} 这四个类同属于InputStream家族,他们就是一个经典的装饰器模式设计。其中
InputStream 具有读入功能的抽象被装饰器。
FileInputStream 具有读入文件功能的具体被装饰器。
FilterInputStream 具备装饰器的抽象意义。
BufferedInputStream 具有具体功能(缓冲功能)的装饰器。
这个时候后我想设计一个具有缓冲功能的读取文件中的字节的行为:
Java代码
public void IOTest{
//缓冲装饰器包装文件字节输入流
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("C://decorator.txt"));
//读取内容
bis.read();
}
public void IOTest{
//缓冲装饰器包装文件字节输入流
BufferedInputStream bis=new BufferedInputStream(new FileInputStream("C://decorator.txt"));
//读取内容
bis.read();
} IO类库中还有很多其他的装饰器,比如处理基本数据类型的DataInputStream,处理ZIP文件流的ZipInputStream,等等。只要我们想的到的行为,都可以用这些装饰器包装组合来完成。就这一点,装饰器绝对是Perfect。
但是装饰器模式也有一个算不上缺点,但也不太好的地方。这种设计常常造成大量的小类存在,数量之大可能会给类消费者很大的困扰。是吧!学习Java的IO流是不是特痛苦呀......
备注:JDK中的集合类库也使用了装饰者模式,在《集合类库(六):集合类的相互包装 》中有详细介绍。
分享到:
相关推荐
使用装饰模式时,首先创建一个基础的流对象,然后根据需求选择合适的装饰器对其进行包装。例如,如果我们需要从文件中读取数据并进行缓冲处理,可以这样操作: ```java InputStream in = new FileInputStream("file....
在Java IO类库中,装饰器模式被广泛使用,以灵活地扩展类的功能,而避免了使用继承带来的复杂性。装饰器模式的核心在于,它定义了一个与组件接口相同的接口,因此可以在运行时动态地将责任附加到对象上。 在Java IO...
支持Fastify版本3.x安装npm i fastify-socket.io用法需要fastify-socket.io并将其注册为任何其他插件,它将添加一个io装饰器。 const fastify = require ( 'fastify' ) ( )fastify . register ( require ( 'fastify...
Java IO 还包括Filter流,可以用来装饰其他流,添加额外的功能,如缓冲、转换或加密。 二、commons-io-2.5.jar 功能 Apache Commons IO 提供的增强功能包括: 1. 文件操作:`FileUtils` 类提供了大量静态方法,用于...
IO过滤器:一系列的装饰器类,可以轻松地在现有流上添加缓冲、计数、关闭监听、线路结束符转换等功能。 目录遍历和文件查找工具。 字节顺序标记(BOM)处理。 大文件支持:部分方法设计用于处理大型文件,避免一次性...
装饰器模式是一种设计模式,它的主要目的是在不修改已有对象的基础上,动态地为对象增加新的功能。这种模式在软件工程中被广泛应用,特别是在需要扩展功能而又不希望改动原有代码的情况下,装饰器模式提供了很好的...
此外,为了提高性能和功能,Java IO还提供了大量的过滤器流和装饰器模式来增强基本流的功能。 #### 二、Java IO系统的组成 Java IO系统由多个层次组成,每个层次都有其特定的职责和功能: - **核心流**:包括`...
此外,Filter流(过滤流)如BufferedInputStream和PrintStream,可以被用作装饰器模式,添加额外的功能,如缓冲、转换编码或者验证数据。 Java NIO(New IO)是Java 1.4引入的一个扩展,它提供了非阻塞I/O操作和...
3. **装饰器I/O类**:如 `BufferedInputStream`、`BufferedOutputStream`、`DataInputStream` 和 `DataOutputStream` 等,它们通常用来增强基础流的功能,比如添加缓存或数据格式化的能力。 ### Java IO的总体结构 ...
在Java IO库中,存在一对“装饰器”流,即BufferedInputStream和BufferedReader。它们提供缓冲功能,可以显著提高数据读写的效率。例如,使用BufferedReader.read()方法可以一次性读取一行文本,而不是一个字符一个...
【Python装饰器详解】 装饰器在编程中是一种强大的工具,尤其在Python中,它使得代码更加灵活和可扩展。装饰器本质上是一个接收函数并返回新函数的函数,它允许我们修改或增强函数的行为,而无需修改函数本身的源...
在Java的IO库中,装饰器模式得到了广泛应用。例如,`BufferedInputStream`就是一种装饰器,它包装了基本的`InputStream`,增加了缓冲功能,使得读取数据更加高效。装饰器模式下,高级流(如`BufferedInputStream`)...
Java的IO类库中,装饰器模式的实现使得IO流的使用非常灵活。客户端代码可以将装饰器组合起来使用,以实现复杂的数据处理逻辑。例如,可以先创建一个BufferedInputStream来提供缓冲功能,然后通过DataInputStream读取...
1. 装饰器模式(Decorator):Java IO系统中广泛使用该模式,通过装饰器模式来扩展IO流的功能。 五、举例说明: 1. Java IO的类和接口:通过查看Java IO包下的类和接口,可以了解到Java在IO上的丰富支持,包括各种...
除此之外,还有FilterInputStream和FilterOutputStream等过滤流,它们可以被用来组合多个装饰器,实现更复杂的流处理逻辑。 此外,Java NIO(New IO)在Java 1.4引入,是对传统IO的补充,提供了非阻塞IO、选择器和...
Java的IO流体系是Java平台的核心...总之,Java的IO流体系通过其对称性质和装饰器模式,提供了灵活且强大的数据输入输出解决方案。理解这个体系结构,可以帮助开发者更好地利用Java进行文件操作、网络通信以及数据处理。
在Java编程语言中,I/O(输入/输出)是处理数据传输的核心部分,尤其是在处理文件、网络通信或者系统间的数据交换时...此外,了解和使用装饰器模式也是理解Java IO流设计的关键,因为很多处理流就是装饰器模式的应用。
接下来是"三大器",这通常指的是装饰器(Decorator)、生成器(Generator)和上下文管理器(Context Manager)。装饰器允许我们在不修改原始函数代码的情况下,添加额外的功能或行为。生成器则是一种特殊的迭代器,...
与节点流不同,过滤流本身并不直接连接到数据源或目标,而是作为中间层,通过装饰器模式对底层流进行增强。 ##### 输入流的处理流作用 - **功能增强**:如字符编码转换、压缩解压等。 - **性能优化**:通过缓冲...
FilterInputStream和FilterOutputStream是过滤流,可以作为装饰者模式的实例,用于在原有流的基础上添加额外功能,如数据校验、压缩等。 以上内容涵盖了Java IO的基本知识点,通过理解和掌握这些概念,开发者可以...