定义
动态地给一个对象添加额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。
代码实现
抽象构件:
public abstract class Component {
//抽象的方法
public abstract void operate();
}
具体构件:
public class ConcreateComponent extends Component {
@Override
public void operate() {
System.out.println("do something");
}
}
抽象装饰器:
public abstract class Decorator extends Component{
Component component;
public Decorator(Component component) {
this.component = component;
}
@Override
public void operate() {
this.component.operate();;
}
}
具体装饰类:
public class ConcreteDecorator1 extends Decorator {
public ConcreteDecorator1(Component component) {
super(component);
}
private void method1() {
System.out.println("修饰1");
}
@Override
public void operate() {
this.method1();
super.operate();
}
}
public class ConcreteDecorator2 extends Decorator {
public ConcreteDecorator2(Component component) {
super(component);
}
private void method2() {
System.out.println("修饰2");
}
@Override
public void operate() {
super.operate();
this.method2();
}
}
场景类:
public static void main(String[] args) {
Component component = new ConcreateComponent();
//第一次修饰
component = new ConcreteDecorator1(component);
//第二次修饰
component = new ConcreteDecorator2(component);
component.operate();
}
优点
- 装饰类和被装饰类独立发展,互补耦合。意思就是Component不知道Decorator存在,Decorator也不用知道具体的构件。
- 是继承关系的一个替代方案。无论装饰多少层,装饰后依然返回Component。
- 动态扩展一个实现类的功能,如果不需要,直接不进行装饰,卸载即可。
缺点
多层装饰增加系统的复杂度。
适用场景
- 需要扩展一个类的功能
- 动态给一个对象增加功能,也可以动态撤销
实践
装饰模式是对继承的有力补充。但是继承不是动态的,扩展性差。什么意思呢?比如Father, Son, GrandSon三个继承关系类,现在需求要对Son增强功能,难道要修改Son类中增加修改方法吗? 但会影响GrandSon,特别是GrandSon有多个情况, 但是可以通过装饰器模式添加一个SonDecorator来实现,原来的程序不进行变更。
另外JDK源码IO中也用到了装饰器模式。
抽象构件: InputStream
具体构件: FileInputStream
抽象装饰器: FilterInputStream
具体装饰器: BufferedInputStream, DataInputStream