现在的位置: 首页 > 综合 > 正文

Java IO 中的设计模式

2013年06月01日 ⁄ 综合 ⁄ 共 2527字 ⁄ 字号 评论关闭

引言:

单纯学设计模式和Java类库的学习效果都不会很好。设计模式和Java类库的关系就好像九阴真经和北斗阵法的关系,一个是练功原理,一个是用原理实现的招式,郭靖在轩辕台上忘记危险而专注思考就是领悟到了其中的两者结合而来的妙处。设计模式这样的东西(增加开发时间和成本,提高可扩展性和可维护性),只有运用在基础类库中才能体现出他的价值,设计模式是用来打基础的,现实中的项目如果用设计模式难免会出现费力不讨好的情况。学习类库的关键是掌握她使用的设计模式,这样很学的扎实并且不容易忘。

Java IO 类图

图片来自:点击打开链接

下面这篇文章对IO中运用的设计模式进行了很好的阐述,文章如下:

作者:终南   <li.zhongnan@hotmail.com>

设计模式是一个很理论的,也是一个很经验的东西。纯粹照着文档去理解设计模式不是一个好的方式,当经验有所增长的时候,回过头来看看设计模式这个比较玄的东西,还是比较有好处和用处的。

其实,在JDK中就使用了很多设计模式,为类库的可重用性、可扩展性和灵活性提供了强有力的支持。

JDK的I/O包中就主要使用到了两种设计模式:Adatper模式和Decorator模式

1。Adatper模式

Adatper模式又称为Wrapper模式。Wrapper模式这个词汇也许更能很好的理解其含义。比如JNI技术,具体的实现是C语言写的,不过最后提供给用户的却是Java程序,也就是用Java包装/包裹/Wrapper了C代码。这就是Wrapper模式,也即Adapter模式。

通过使用Adatper模式,可以使得通常因为接口不兼容而不能在一起工作的类工作在一起,做法是将类自己的接口包裹在一个已存在的类中。

InputStreamReader是Java IO中将byte流转换为char流的桥梁,其从从byte流中读取字节信息然后将其解码为char流,提供Reader接口所定义的方法。

从代码来看,InputStreamReader类中定义了一个 StreamDecoder 类的变量sd:

    private final StreamDecoder sd;

当通过构造器 InputStreamReader(InputStream in) 创建一个InputStreamReader的实例时,通过传入的参数 InputStream 创建一个 StreamDecoder 实例 sd:

    public InputStreamReader(InputStream in) {
super(in);
        try {
     sd = StreamDecoder.forInputStreamReader(in, this, (String)null); // ## check lock object
        } catch (UnsupportedEncodingException e) {
     // The default encoding should always be available
     throw new Error(e);
}
    }

实现Reader接口的read()方法的代码为:

    public int read() throws IOException {
        return sd.read();
    }

我们可以看到,实际上是调用StreamDecoder 的 read()方法来实现的。

形象地说,就是:

你和我合得来,和别人和不来,而我与别人合得来,你让我干活,我让别人干活。

除此之外,Java IO包下还有其他一些类使用了此种模式,如:

OutputStreamWriter:将char流转换成byte流。也就是使用Writer中的方法,但是结果将字符写入到byte流中。

StringReader/StringWriter:实现Reader/Writer到String的转换。

FileInputStream/FileOutputStream:连接File与InputStream/OutputStream,从而实现对文件的读写。

最后,看一下Adatper模式的图形说明:


2。Decorator模式

Decorator模式,顾名思义,就是修饰、装饰、锦上添花的意思。如果一个类已经有一些功能,你如果还想添加一些其他的功能,就可以使用Decorator模式。

通过使用Decorator模式,可以在运行时扩充一个类的功能。其原理是:增加一个装饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造器的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。装饰类必须和被装饰的类有相同的接口。

看看Java IO中的 LineNumberReader 类,该类继承自BufferedReader。可以将其看成实现了Reader接口,并且添加了readLine()、getLineNumber()、setLineNumber()这几项功能的类。

该类提供了两个构造器:

LineNumberReader(Reader in)

LineNumberReader(Reader in, int sz)

将原来的、被装饰的Reader作为构造器参数,除了实现Reader接口要求的功能外,还增加添加了新的功能。

在应用中,如果我们需要一行一行的从文件中读取字符,就可以利用LineNumberReader类来完成这样的这样的功能:

LineNumberReader reader = new LineNumberReader(new FileReader("file_name"));

在这里,Reader是一个公共接口,FileReader是一个被装饰的类,LineNumberReader 是装饰类。LineNumberReader 和 FileReader都实现了Reader接口,FileReader作为LineNumberReader 来构造一个LineNumberReader 实例。

对于Decorator模式,可以这样形同:

我们都给老板打工,我们配合做同样的事情,以我作为主,以你与老板联系为主,我做的差不多了,你帮我把把关,美化一下,最后由你想老板汇报。

Decorator模式可以用以下图形说明:


抱歉!评论已关闭.