首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

IO 装点器

2012-10-08 
IO 装饰器http://hxraid.iteye.com/blog/432658继承是OOP程序设计的一大特点,但其实对于很多复杂问题来说,

IO 装饰器
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中的集合类库也使用了装饰者模式,在《集合类库(六):集合类的相互包装 》中有详细介绍。

热点排行