python中的装饰器大家可能都知道,但是现在我们要说java,并且要说到java的io流。
装饰器模式,是对对象的装饰,是对对象能力的扩充。
它和继承是不一样的,继承是对类能力的扩充。
装饰器模式同样是面向接口编程的,最重要的一点是,装饰器要包含被装饰的对象。
举个例子。
首先,我们要有一个抽象组件:
public interface Component {
void doSomething();
}
它定义了顶级的方法。
然后有一个具体组件来实现这个抽象组件:
public class ConcreteComponent implements Component {
@Override
public void doSomething() {
System.out.println("function A");
}
}
具体组件的功能是“function A”,可以理解为,这是一个很基础的功能。
现在出现了我们的装饰器:
public class Decorator implements Component {
private Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void doSomething() {
component.doSomething();
}
}
装饰器要包含被装饰的对象。
所以在Decorator
中包含了Component
并且实现了Component
。
这个装饰器的功能取决于传进来的是什么Component。
这个装饰器是可以扩展的:
public class MyDecorator1 extends Decorator {
public MyDecorator1(Component component){
super(component);
}
@Override
public void doSomething() {
super.doSomething();
this.anotherThing();
}
private void anotherThing() {
System.out.println("function B");
}
}
public class MyDecorator2 extends Decorator{
public MyDecorator2(Component component){
super(component);
}
@Override
public void doSomething() {
super.doSomething();
this.doAnotherThing();
}
private void doAnotherThing() {
System.out.println("function C");
}
}
我们测试一下:
public class TestDecorator {
public static void main(String[] args) {
Component component = new MyDecorator1(new MyDecorator2(new ConcreteComponent()));
component.doSomething();
}
}
结果:
function A
function C
function B
最外层我们只需用Component
接收即可。
我们new
了MyDecorator1
,所以它有function B。
同时它又具备了另一个装饰器的function C和最底层的function A。
如果只有两层:
public class TestDecorator {
public static void main(String[] args) {
Component component = new MyDecorator1(new ConcreteComponent());
component.doSomething();
}
}
那么:
function A
function B
上面的写法似曾相识:
public class MyDecoratorStream extends FilterInputStream {
protected MyDecoratorStream(InputStream in) {
super(in);
}
public static void main(String[] args) throws Exception {
InputStream in = new MyDecoratorStream(new BufferedInputStream(new FileInputStream("a")));
}
}
我自己写了一个装饰器扩展流MyDecoratorStream
,它继承了装饰器FilterInputStream
。
同样的,另一个装饰扩展流BufferedInputStream
也继承了FilterInputStream
。
而我们的FilterInputStream
就是装饰器,它实现了抽象组件,并且包含抽象组件:
而FileInputStream
则像一个具体组件。
装饰器模式的好处是,不会出现大量的继承类,同时功能完备。