1、装饰模式的概念
装饰模式以对客户透明地方式动态地给一个对象附加上更多的责任。换言之,客户端并不会觉得对象在装饰前和装饰后有什么不同。装饰模式可以在不创造更多子类的情况下,将对象的功能加以扩展。
2、装饰模式中的角色
(1)抽象构建(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。如:InputStream。
(2)具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。如:FileInputStream。
(3)装饰(Decorator)角色:持有一个构件对象的实例,并定义一个与抽象构建接口一致的接口。如:FilterInputStream。
(4)具体装饰(Concrete Decorator)角色:负责给构件对象“贴上”附加的责任。如:BufferedInputStream、DataInputStream。
3、举例说明
(1)抽象构建角色
package com.iotek.decorator;
public interface Component {
    void doThingA();
}
(2)具体构件角色
package com.iotek.decorator;
public class ConcreteComponent implements Component {
    @Override
    public void doThingA() {
        System.out.println("do A thing.");
    }
}
(3)装饰角色
package com.iotek.decorator;
public class Decorator implements Component {
    private Component component = null;
    public Decorator(Component component) {
        this.component = component;
    }
    @Override
    public void doThingA() {
        component.doThingA();//调用被装饰对象的方法
    }
}
(4)具体装饰角色1
package com.iotek.decorator;
public class ConcreteDecorator1 extends Decorator {
    public ConcreteDecorator1(Component component) {
        super(component);
    }
    public void doThingA(){//调用被包装类的方法
        super.doThingA();
        doThingB();
    }
    //扩展的方法
    private void doThingB(){
        System.out.println("do B thing.");
    }
}
(5)具体装饰角色2
package com.iotek.decorator;
public class ConcreteDecorator2 extends Decorator {
    public ConcreteDecorator2(Component component) {
        super(component);
    }
    public void doThingA(){//调用被包装类的方法
        super.doThingA();
        doThingC();
    }
    //扩展的方法
    private void doThingC(){
        System.out.println("do C thing.");
    }
}
(6)测试类
package com.iotek.decorator;
public class Test {
    public static void main(String[] args) {
        ConcreteComponent concreteComponent = new ConcreteComponent();
        //concreteComponent.doThingA();
        ConcreteDecorator1 cd1 = new ConcreteDecorator1(concreteComponent);
        //cd1.doThingA();
        ConcreteDecorator2 cd2 = new ConcreteDecorator2(cd1);
        cd2.doThingA();
    }
}