定义:
Attach additional responsibilities to an object dynamically keeping the same interface. Decorators provide a flexible alternative to subclassing for extending functionality.
动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。能够在不修改任何底层代码的情况下,给你的或别人的对象赋予新的职责。
类图:
//抽象组件
public abstract class Component{
public abstract void operate();
}
//具体组件
public class ConcreteComponent extends Component{
@Override
public void operate(){
...
}
}
//抽象装饰者
public abstract class Decorator extends Component{
private Component comp = null;
public Decorator(Component comp){
this.comp = comp;
}
@Override
public void operate(){
comp.operate();
}
}
//具体装饰者
public class ConcreteDecorator1 extends Decorator{
public ConcreteDecorator1(Component comp){
super(comp);
}
private void additionalFunc(){//附加功能
...
}
@Override
public void operate(){
additionalFunc();
super.operate();
}
}
【例】java.io包中的代码示例:
//抽象组件
public abstract class InputStream{
public abstract int read() throws IOException;
......
}
//具体组件
public class FileInputStream extends InputStream{
public native int read() throws IOException;。。。
}
//抽象装饰者
public class FilterInputStream extends InputStream {
/**
* The input stream to be filtered.
*/
protected volatile InputStream in;
protected FilterInputStream(InputStream in) {
this.in = in;
}
public int read() throws IOException {
return in.read();
}
}
//具体装饰者
public class BufferedInputStream extends FilterInputStream {
public BufferedInputStream(InputStream in, int size) {
super(in);
...
}
public synchronized int read() throws IOException {//加上自己的行为,以达到特定的目的
if (pos >= count) {
fill();
if (pos >= count)
return -1;
}
return getBufIfOpen()[pos++] & 0xff;
}
}
角色:
1)Component抽象组件
是一个接口或抽象类,是最核心的、最原始的对象。【例】如java.io.InputStream
2)ConcreteComponent具体组件
抽象组件的实现,我们要装饰的就是它。【例】如java.io.FileInputStream
3)Decorator装饰者
一般是抽象类,但不一定包含抽象方法。必然有一个private的变量指向Component。【例】如java.io.FilterInputStream
4)ConcreteDecorator具体装饰者
把最核心、最原始的对象装饰成其他东西;在被装饰者的行为前后,加上自己的行为,以达到特定的目的。【例】如java.io.BufferedInputStream
优点:
- 组件和装饰者可以独立发展,而不互相耦合。
- 是继承关系的一个替代方案。若使用继承时子类非常多,会导致类爆炸,可用装饰者模式。——使用组合而非继承,可以再运行时动态地进行扩展
- 可以动态地扩展一个实现类的功能。如要增加新的修饰条件,增加一个ConcreteDecorator即可。
缺点:
多层的装饰是比较复杂的。
使用场景:
- 需要扩展一个类的功能时;给一个类增加附加功能。
- 动态地给一个类增加功能;并能动态地撤销。
- 需要为一批的兄弟类进行改装或加装功能时。