定义:
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即可。
缺点:
多层的装饰是比较复杂的。
使用场景:
- 需要扩展一个类的功能时;给一个类增加附加功能。
- 动态地给一个类增加功能;并能动态地撤销。
- 需要为一批的兄弟类进行改装或加装功能时。