作者qrtt1 (null)
看板java
标题Re: [问题] 新手请教一个写入档案的问题
时间Sat May 30 23:14:44 2009
刚好 First Head Design Pattern 的 ch3 有试阅 :D
http://oreilly.com/catalog/hfdesignpat/chapter/ch03.pdf
Java I/O 正是 real world decorator pattern 的例子。
decorator pattern 常被抱怨因为子类别太多难以看懂,
不过这件事通常要靠学习 decorator pattern 来解决。
请看第 24 页(或页码101),
decorator pattern 有 4 类基本的角色
1. 抽象的元件,用来定义基本行为
2. 实体元件,能直接使用的元件。
3. 抽象的装饰者,定义装饰者基本行为
4. 实体装佣者,实作装饰者行为。
InputStream 就是 [1] 抽象元件。
它定义所有 InputStream 衍生类别应用的共通行为。
而 FileInputStream、StringBufferInputStream、ByteArrayInputStream 等
都是能直接使用的元件[2]。
所谓「能直接」使用的意义是:
1. 它是最初的元件状态来源,
FileInputStream 的 Input 需来自 File
建构子需为 File 物件或 FileDescriptor 或档案路径
StringBufferInputStream 的 Input 需来自 String
建构子只能是字串
ByteArrayInputStream 的 Input 需来自 byte[]
建构子需为 byte[] 或 byte[] 区段
2. 它的实作不能透过装饰而来,因为没有状态的本体,装饰没有意义。
先掌握非装饰用的元件,再来看装饰者的基本行为:
http://java.sun.com/j2se/1.4.2/docs/api/java/io/FilterInputStream.html
它有唯一的建构子 InputStream。
这说明它的风格是透过建构的过程,实现装饰的效果。
因此,下面这样的用法是相当常见的:
new LineNumberInputStream(
new BufferedInputStream(
new FileInputStream("foo.txt")
)
);
FileInputStream 是实体元件负责提供状态的来源,
BufferedInputStream 装饰 FileInputStream 提供读档时的 buffer
因为 read() 方法只会读出适当的笔数,这样做没什麽效率。
透过 BufferedInputStream 预先读出一「块」资料,放在 buffer 内
read() 不会频繁地读写硬碟,而是在 buffer 内的资料没有时,
才会有实际的读取作用。
LineNumberInputStream 提供行号的管理,
我想应该就是在 read() 要吐出资料前判断是否有经过换行字元吧。
当我们认识 decorator pattern 并理解 Java IO 是这样设计。
那麽面对再多的 subclass 就无需畏惧了。
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 61.231.55.86