装饰模式:动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator(装饰)模式相比生成子类更为灵活。
   适用环境:
  • 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
  • 处理那些可以撤消的职责。
  • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

    本模式中包含的角色:
    抽象构件(Component):给出一个抽象接口,以规范准备接收附加责任的对象。
    具体构件(Concrete Component):定义一个接收到附加责任的类。
    装饰(Decorator):持有一个构件对象的实例,并定义与抽象构件一致的接口。
    具体装饰(Concrete Decorator):负责给构件对象贴上附加的责任。
    UML图如下:
    Decorator.jpg

    具体例子:
    先定义抽象构件:

    package decorator;
    //抽象构件接口
    public interface Component{
        
    public void sampleOperation();
    }

    一个具体构件----门:
    package decorator;
    //具体构件-----门
    public class  Door implements Component{
        
    //实现方法
        public void sampleOperation(){
            System.out.println(
    "build a door");
        }

    }

  • 装饰(抽象类):
    package decorator;

    public abstract class Decorator implements Component{
        
    //持有一个构件对象的实例
        private Component component;
        
    //构造方法
        public Decorator(Component component){
            
    this.component=component;
        }

        
    //方法的具体实现
        public  void sampleOperation(){
            component.sampleOperation();
        }

    }

    具体装饰:
    package decorator;
    //具体装饰----把手
    public class Knob extends Decorator{

        
    public Knob(Component component){
            
    super(component);
        }

        
        
    public void sampleOperation(){
            
    super.sampleOperation();
            
    //附加的"责任"
            System.out.println("add a knob");
        }

    }
    package decorator;
    //具体装饰----锁
    public class Lock extends Decorator{

        
    public Lock(Component component){
            
    super(component);
        }

        
    public void sampleOperation(){
            
    super.sampleOperation();
            
    //附加"责任"
            System.out.println("add a lock");
        }

    }
    运行类:
    package decorator;

    public class DecoratorPattern{
        
    public static void main(String[] args){
            Component door
    =new Door();
            Component lock
    =new Lock(door);
            Component knob
    =new Knob(lock);
            knob.sampleOperation();
        }

    }

    运行结果:
    build a door
    add a lock
    add a knob
    Press any key to continue...

    Java 的I/O API就是使用本模式实现的
    ,I/O变种很多,如果都采取继承方法,将会产生很多子类,显然相当繁琐.

    装饰模式与适配器模式的区别与联系:
       这两种模式都有一个别名Wrapper模式,两者的区别:适配器模式的用意是改变所考虑对象的接口,而不一定要改变接口的性能,装饰模式的用意是要保持接口,从而增强所考虑对象的性能。
     

    参考资料:http://blog.csdn.net/qutr/archive/2006/02/27/610788.aspx
    http://www.jdon.com/designpatterns/decorator.htm
    《Java与模式》
    《设计模式速查手册》