decorator 装饰
参考:java.io包详细解说
decorator的结构如下:
MyInterface
|
_______|_______
| |
Myclass Decorator
____|_____
| |
DecoratorA DecoratorB
decorator的目的是在不改变任何原有的类的基础下,添加新的功能(你可以理解为书上说的灵活性)。其中Myclass是你要扩展的类,DecoratorA跟DecoratorB封装了你要扩展的功能,并保存有一个MyInterface的引用。
考虑以下代码:myInterface 是myClass的接口,只声明了一个方法print(),myClass实现了该方法:
public interface MyInterface {
public void print();
}
public class MyClass implements MyInterface {
public void print() {
System.out.println("hello");
}
}
那么假如我们要在不改变原来的myClass的基础上,变成输出“hello world!”,要怎么做呢?
当然我们可以考虑直接写个myClass的子类,helloClass之类,但是要是要求根据环境不同,输出"hello world!",my hello world","my Hello"之类的组合呢?
用继承的方式将不得不写一堆类似的子类来。
decorator,装饰模式的解决方法是,只实现基本的功能,把附加的功能抽出来放一边。首先实现一个公用的装饰器接口。
public interface Decorator extends MyInterface {
void print();
}
DecoratorA的功能是打印出my
public class DecoratorA implements Decorator {
private MyInterface myObject;
public DecoratorA(MyInterface myObject){
this.myObject=myObject;
}
public void print() {
myObject.print();
System.out.println("my");
}
}
DecoratorB的功能是打印出world
public class DecoratorB implements Decorator {
private MyInterface myObject;
public DecoratorB(MyInterface myObject){
this.myObject=myObject;
}
public void print() {
myObject.print();
System.out.println("world");
}
}
这时main函数要打印出 hello my world可简单变为:
new DecoratorB(new DecoratorA(new MyClass())).print();
简单吧?简单的说,就是:
print(){
print("xxx");//可替换成你要添加的任何处理;
myObject.print();//调用基础类的函数;
xxxx; //后续处理
}
java.io分Stream跟reader、writer两大类,这里只详细介绍Stream,并最后两者间的关系。Stream又分inputStream、OutputStream,两者基本是对称的,这里也只介绍InputStream.
java.io.InputStream
|
_______________________|________________________
| |
ByteArrayInputStream FilterInputStream
StringBufferInputStream _____________________|____________________________
FileInputStream | | | |
PipedInputStream DataInputStream BufferedInputStream LineNumInpuStream XXX
(注:xxx是PushbackInputStream,上面的图放不下)
这个图跟最初介绍的hello world的图很像吧?呵呵。
基础的流只有左边4个,这些流代表了数据的来源,所有的流都必须从这四个中之一开始。(注,还有一个RandomAccessFile、File,这两个不在本文介绍范围)。
然后当我们需要什么添加功能,就从右边中选择一个装饰。例如,我们需要缓存功能,那么需要bufferedInputStream装饰:
BufferdInputStream is = new BufferedInputStream(new FileInputStream("xxx.txt"));
假如再要DataInputStream的功能,只要在加一层:
DataInputStream dis = new DataInputStream(new BufferdInputStream(new FileInputStream));