java 设计模式:装饰者模式
简单详解:
1、概念
动态地给一个对象添加一些额外的职责。就增加功能来说, 装饰模式相比生成子类更为灵活。该模式以对客户端透明的方式扩展对象的功能。
2、使用场景
- 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。和继承类似添加相应的职责。
 - 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。
 
3、UML结构图分析

- 抽象构件(Component)角色:给出一个抽象接口,已规范准备接收附加责任的对象。
 - 具体构件(ConcreteComponent)角色:定义一个将要接收附加责任的类
 - 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
 - 具体装饰(ConcreteDecorator)角色:负责给构件对象“贴上”附加的责任。
 
4、实际代码分析
/**
 * 装饰类Component,所有类的父类
 */
public interface Component {
    void sampleOperation();
}
/**
 * 实现抽象部件,具体装饰过程还是交给子类实现
 */
public class Decorator implements Component {
    private Component component;
    public Decorator(Component component){
        this.component = component;
    }
    @Override
    public void sampleOperation() {
        component.sampleOperation();
    }
}
/**
 * 需要装扮的类
 */
public class ConcreteComponent implements Component{
    @Override
    public void sampleOperation() {
    }
}
/**
 * 具体实现
 */
public class ConcreateDecoratorA extends Decorator{
    public ConcreateDecoratorA(Component component) {
        super(component);
    }
    @Override
    public void sampleOperation() {
        super.sampleOperation();
        addPingShengm();
    }
    /**
     * 新增业务方法
     */
    private void addPingShengm() {
        System.out.println("添加绘彩1");
    }
}
/**
 * 具体实现
 */
public class ConcreateDecoratorB extends Decorator{
    public ConcreateDecoratorB(Component component) {
        super(component);
    }
    @Override
    public void sampleOperation() {
        super.sampleOperation();
        addPingShengm();
    }
    /**
     * 新增业务方法
     */
    private void addPingShengm() {
        System.out.println("添加绘彩2");
    }
}
举一个实际例子:
工厂需要产生多种水杯,有瓶身绘彩,有不锈钢盖被子,也有不锈钢盖和瓶身绘彩的杯子。(等各种需求)
假如说采用继承子类的方式。如下code:
/**
 * 创建水杯的接口包含四个方法,底座,盖子,瓶身,一个实现功能product
 */
public interface IShuiBei {
    void dizuo();
    void gaizi();
    void pingsheng();
    void product();
}
/**
 * 水晶杯实现类
 */
public class ShuiJInBei  implements IShuiBei,Component {
    @Override
    public void dizuo() {
        System.out.println("水晶底座");
    }
    @Override
    public void gaizi() {
        System.out.println("水晶盖子");
    }
    @Override
    public void pingsheng() {
        System.out.println("水晶瓶身");
    }
    @Override
    public void product() {
        dizuo();
        gaizi();
        pingsheng();
    }
}
/**
 * 添加绘彩的水晶杯
 */
public class HuiCaiShuiJinBei extends ShuiJInBei{
    @Override
    public void pingsheng() {
        super.pingsheng();
        System.out.println("添加绘彩");
    }
}
/**
 * 不锈钢杯子盖的水晶杯
 */
public class HuiJinGangGaiBei extends ShuiJInBei{
    @Override
    public void gaizi() {
        System.out.println("不锈钢杯盖");
    }
}
/**
 * 不锈钢杯子盖的水晶杯带彩绘
 */
public class HuiCaiShuiJinGangGaiBei extends ShuiJInBei{
    @Override
    public void gaizi() {
        System.out.println("不锈钢杯盖");
    }
 @Override
    public void pingsheng() {
        super.pingsheng();
        System.out.println("添加绘彩");
    }
}
//运行
        HuiCaiShuiJinBei huiCaiShuiJinBei = new HuiCaiShuiJinBei();
        HuiCaiShuiJinGangGaiBei huiCaiShuiJinGangGaiBei = new HuiCaiShuiJinGangGaiBei();
        ShuiJInBei shuiJInBei = new ShuiJInBei();
        huiCaiShuiJinBei.product();
        huiCaiShuiJinGangGaiBei.product();
        shuiJInBei.product();
一共创建三个子类,一个父类,当然如果需求更多的话,子类会不断的增加。
装饰类实现如上功能code:
/**
 * 实现抽象部件
 */
public class ShuijinbeiDecorator implements IShuiBei{
    IShuiBei iShuiBei;
    public ShuijinbeiDecorator(IShuiBei iShuiBei){
        this.iShuiBei = iShuiBei;
    }
    @Override
    public void dizuo() {
        iShuiBei.dizuo();
    }
    @Override
    public void gaizi() {
        iShuiBei.gaizi();
    }
    @Override
    public void pingsheng() {
        iShuiBei.pingsheng();
    }
    @Override
    public void product() {
        dizuo();
        gaizi();
        pingsheng();
    }
}
/**
 * 钢盖实现类
 */
public class GangGaiDecorator extends ShuijinbeiDecorator{
    public GangGaiDecorator(IShuiBei iShuiBei) {
        super(iShuiBei);
    }
    @Override
    public void gaizi() {
        System.out.println("不锈钢杯盖");
    }
}
/**
 * 彩绘实现类
 */
public class CaihuiDecorator extends ShuijinbeiDecorator{
    public CaihuiDecorator(IShuiBei iShuiBei) {
        super(iShuiBei);
    }
    @Override
    public void pingsheng() {
        super.pingsheng();
        System.out.println("添加绘彩");
    }
}
//运行
        IShuiBei iShuiBei = new ShuiJInBei();
        iShuiBei.product();
        iShuiBei = new CaihuiDecorator(iShuiBei);
        iShuiBei.product();
        iShuiBei = new GangGaiDecorator(iShuiBei);
        iShuiBei.product();
        iShuiBei = new ShuiJInBei();
        iShuiBei = new GangGaiDecorator(iShuiBei);
        iShuiBei.product();看到如上代码你大概会恍然大悟,装饰模式如果在你的子类特别多,用装饰模式很好,但是比较容易出错哦。
装饰模式的优点
- 装饰模式与继承关系的目的都是要拓展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
 - 装饰模式允许系统动态决定“贴上”一个需要的“装饰”,或者“除掉”一个不需要的“装饰”。继承关系则不同,继承关系是静态的,它在系统运行前就决定了。
 - 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类的排列组合。
 
装饰模式的缺点
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另外一方面,使用装饰模式会产生比使用继承关系所产生的更多的对象。而更多的对象会使得查找错误更为困难,特别是这些对象在看上去极为相似的时候。
装饰模式在Android中的实际应用
context类簇