`
frank-liu
  • 浏览: 1682227 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Decorator Pattern和Java IO

阅读更多

Decorator之前

在Java程序中,我们常会在IO的时候用到类似于如下的代码:

 

InputStream in = new BufferedInputStream(
                          new FileInputStream("test.txt"));
 

从代码本身的直观意义来说,这部分代码很好理解。

1.使用FileInputStream打开test.txt文件。使用BufferedInputStream类封装了这个类之后,返回的对象就具备了缓冲部分数据的功能。

2. 比较有意思的一点在于,虽然我们用BufferedInputStream封装了前面的对象,但是我们还是可以把它当成一个InputStream类的对象来使用。

粗粗看来,这种写法似乎也没有什么特殊的。假定我们自己从最初的角度来设计这个问题,可能会采用一个类似于继承的办法,如下图所示:

最初设想

 

这种设想的一个基本点是,如果每次需要对原有的类做增强的时候,我们可以通过对在原有类的基础上派生出一个新的类来。这样既不会修改原来的类,也可以实现良好的可扩充。

回头看前面那个示例代码,我们会发现这样的设计其实会存在一个隐藏的问题的。

1.如前面所示,如果我们每次需要增加新的功能的时候,都继承一个新的类出来。如果我们需要一个既有FileInputStream类的特性同时又有BufferedInputStream的特性的类呢?这下问题就来了,如果我们继续继承这两个类的话,可能就需要定义一个新的类。或者我们也可以再从InputStream派生一个新的类,有两个类的特性。这样的话,我们可能就不可避免的在新的类中要重复部分FileInputStream和BufferedInputStream的代码。重复的代码显得比较讨厌,你懂的。

2. 如果我们需要一个类具有多种特性呢?比如说,我既要有BufferedInputStream的特性,然后还需要一些自定义的特性,比如说将里面某些字符的大小写变化一下。那该怎么办呢?总不能再去从多个类中间来继承吧?如果这样的话,我们在类继承结构中每增加一种新的特性,这个新的特性就可能和其他的类可能形成一种组合的关系。如果再考虑到组合的顺序和次数的话...显然,类会呈现出一个爆炸式的增长。

综上所述,问题的根源在于,我们要求类能够根据多个不同的特性部分进行灵活的组合时,采用继承的方法是不合适的。

 

Decorator的引申和推导

现在我们看看decorator模式的uml图:

decorator

 

这个图中间有几个比较有意思的地方,

1. ConcreteComponent是某一个具体的类,相当于前面的FileInputStream。它是作为一个封装的最核心部分。就好像是包包子的馅,没有它就不能成为包子了。

2. ConcreteDecoratorA,B这些类都有一个封装的对象,然后每个具体的类针对该封装的对象来添加新的特性。这就像是往包子馅外面裹皮,具体是裹成什么样的就看你要添加什么新特性。

3. 还有一个问题就是一直让人开始比较困惑的。既然前面的设计方式会带来类爆炸的问题,这个设计是怎么解决的呢?问题的关键点就在于Decorator类和ConcreteDecorator类的继承。通过Decorator类具体封装了一个ConcreteComponent对象。因为继承自同一个类,我们可以把它当成一个父类对待。同样,每个具体的ConcreteDecorator在添加新的特性时,就相当于在一个封装的对象里添加东西,而不需要去继承。而且比较有意思的是,我们这么封装后的对象,也可以当成一个抽象的父类进行进一步的封装。这种设计思想不是正好利用到了常用的一个设计原则么?优先考虑组合而不是继承。

 

Decorator模式在Java I/O包中的应用

Decorator模式可以说在java的IO包里头得到了重度的应用。一个典型的和InputStream类关联的类关系图就可见一斑:

decorator

从图中我们可以看到,InputStream就相当于最高的父类。而FileInputStream, StringBufferInputStream...这几个类相当于用来被包装核心。如最前面的代码所示,它们只能用在最里边。而那些用来包装的类如BufferedInputStream...这些都继承自FilterInputStream类。FilterInputStream相当于前面的Decorator类。

 

总结

如果把前面那部分弄明白之后,再来看java io包中间的类的时候就不会觉得很晕了。可以简单的做一个这样的归纳。

Java IO一般分为两类,一类是面向字节的,采用InputStream或者OutputStream。还有一类是面向字符的,采用Reader和Writer。而针对这些所有的类的结构都采用了Decorator的结构。所以,根据命名的约定,我们就可以很容易猜出里面哪些类是干什么的以及在这个类结构中起什么作用。用一句话来概括java io包中的类的话,就是这个包中基本上就是包含了InputStream, OutputStream,Reader和Writer这四大家族和他们的小喽罗们:)

  • 大小: 34.4 KB
  • 大小: 63.3 KB
  • 大小: 102.9 KB
分享到:
评论
1 楼 Mojarra 2012-06-05  
好文章,比单纯说decorator模式精彩的多

相关推荐

    DecoratorPattern.rar

    在"DecoratorPattern.rar"这个压缩包中,包含了装饰器模式的简单案例demo和一个使用MindMaster绘制的脑图。通过这个案例,我们可以深入理解装饰器模式的工作原理和应用场景。 1. 装饰器模式的基本结构: - ...

    java_io详解

    Java的IO模型采用了装饰者模式(Decorator Pattern),这使得开发者可以根据具体需求动态地组合不同的流类来构建所需的IO功能。例如,如果需要一个具有缓冲功能的文件输入流,可以通过组合`FileInputStream`和`...

    java Decorator装饰模式例子

    装饰模式(Decorator Pattern)是设计模式中的一种结构型模式,它允许在运行时给对象添加新的行为或职责,而无需改变对象的类。在Java中,装饰模式通常通过继承和组合来实现,使得代码具有更好的扩展性和灵活性。...

    Java_IO完全总结

    它提供了一个面向对象的API,并且在Java IO库中采用了装饰器模式(Decorator Pattern)来减少类的数量,使得整个框架既灵活又易于扩展。Java的IO系统主要由两大块组成: 1. **堵塞型IO (Blocking IO)**:位于`java.io...

    Java_IO流详解

    Java的IO流设计非常优雅,采用了装饰者模式(Decorator Pattern),允许用户动态地组合不同的流,以实现所需的功能。例如,结合使用`FileInputStream`和`BufferedInputStream`可以获得一个具有缓冲功能的文件输入流...

    Java_IO详细教程

    这段代码展示了 Java 中常见的 IO 处理方式,同时引出了一个重要的设计模式——装饰者模式(Decorator Pattern)。装饰者模式是一种结构型设计模式,用于在不改变现有对象结构的情况下动态地给该对象添加新的功能。 ...

    设计模式_java语言中的应用

    在Java中,`java.io.InputStreamReader`和`java.io.OutputStreamWriter`是字符流和字节流之间的适配器。 6. 桥接模式(Bridge Pattern):将抽象部分与实现部分分离,使它们可以独立变化。Java集合框架中的`List`, ...

    探寻Java源码中的设计模式

    7. 装饰器模式(Decorator Pattern):装饰器模式动态地给一个对象添加额外的职责,如`java.io.InputStream`和`java.io.FilterInputStream`,后者可以在不改变原有行为的基础上增加新的功能。 8. 桥接模式(Bridge ...

    设计模式Java版各个实现代码

    5. **装饰器模式(Decorator Pattern)**:动态地给一个对象添加一些额外的职责,可以独立增加功能,同时保持接口一致。Java中的IO流类库就大量使用了装饰器模式。 6. **适配器模式(Adapter Pattern)**:将一个类...

    《Java与模式 阎宏 摘录》.doc 更新中……

    Java的IO流设计就广泛应用了装饰器模式,例如BufferedReader和InputStreamReader等。 此外,阎宏的书可能还会涵盖其他设计模式,如策略模式、适配器模式、桥接模式、建造者模式等,以及如何在Java中有效地使用这些...

    Java与模式-我修改过的源代码

    4. **装饰器模式**(Decorator Pattern):动态地给对象添加新的行为或责任,而不影响其他对象。Java的IO流就是很好的例子。修改可能包括扩展更多的装饰类,以提供更多功能组合。 5. **策略模式**(Strategy ...

    10、JavaSE:IO流.pdf

    Java SE中的IO流是用于Java程序中输入和输出操作的一种机制,它将数据处理看作是水流的方式,通过“流”的方式进行读写操作。J2SDK提供了多种流类,以处理不同类型的数据。流的概念来源于现实世界中的水流,形象地...

    Java_在终极设计模式包中掌握经典设计模式和实际示例.zip

    装饰器模式(Decorator Pattern)是一种结构型设计模式,用于在运行时为对象添加新的行为或职责,而无需修改其原有代码。Java的IO流系统就是装饰器模式的一个经典应用。 代理模式(Proxy Pattern)同样属于结构型...

    Java常用设计模式源码

    5. **装饰器模式**(Decorator Pattern):动态地给一个对象添加一些额外的职责,既扩展了功能,又不破坏封装性。在Java IO流体系中广泛应用。 6. **代理模式**(Proxy Pattern):为其他对象提供一种代理以控制对...

    2020版Java设计模式 10 道.pdf

    - 装饰模式(Decorator pattern):动态地给对象添加新的行为或责任,如Java IO中的`BufferedReader`和`BufferedWriter`。 2. **设计模式的含义**: 设计模式是对在软件设计过程中遇到的常见问题的解决方案,是可...

    HeadFirst源代码

    这种模式常用于扩展功能,例如在Java的IO流中,`InputStream`, `OutputStream` 及其各种装饰类如`BufferedInputStream`, `PrintStream`等就是很好的例子。 3. 工厂模式(Factory Pattern):作为创建型模式,工厂...

    10道Java面试必备的设计模式面试题!.pdf

    Java IO 到处都使用了装饰模式,典型例子就是 Buffered 系列类如 BufferedReader 和 BufferedWriter,它们增强了 Reader 和 Writer 对象,以实现提升性能的 Buffer 层次的读取和写入。 五、Java 设计模式的应用场景...

    Java中常见设计模式面试题.docx

    在Java IO库中,`BufferedReader`和`BufferedWriter`是装饰器模式的实例,它们为`Reader`和`Writer`添加了缓冲功能。 5. **设计模式的分类**: - **创建型模式**:包括工厂方法、抽象工厂、单例、建造者和原型模式...

    jiao_java_

    2. **文件系统监控**:通过Java的`java.io.File`类和相关的I/O流,可以监控指定目录下的文件变化,检测潜在的安全威胁。 3. **网络请求监测**:利用Java的`java.net`包,可以创建网络套接字(Socket)来监听和分析...

Global site tag (gtag.js) - Google Analytics