装饰模式

设计原则:类应该对扩展开放,对修改关闭(开闭原则)。

装饰着模式:动态的将责任添加到对象上。若要扩展功能,装饰着将比继承更有弹性。

装饰着模式类图如下:

下面是关于装饰模式的一个典型示例:来自Head First的装饰者模式Demo(星巴兹咖啡):

package com.zjut.json.decoratorPattern;

/**
 * 装饰模式抽象组件
 * 
 * @author json
 *
 * @date 2013-5-6
 */
public abstract class Beverage {
    
    private String description = "Unknown Beverage";
    
    public String getDescription(){
        return description;
    }
    
    public void setDescription(final String description){
        this.description = description;
    }
    
    public abstract double cost();

}
package com.zjut.json.decoratorPattern;

/**
 * 浓缩咖啡-具体组件
 * 
 * @author json
 *
 * @date 2013-5-6
 */
public class Espresson extends Beverage {
    
    /**
     * 增加具体咖啡描述
     */
    public Espresson(){
        setDescription("Espresson");
    }

    @Override
    public double cost() {
        return 1.99;
    }

}
package com.zjut.json.decoratorPattern;

/**
 * 具体组件
 * 
 * @author json
 *
 * @date 2013-5-6
 */
public class HouseBlend extends Beverage {

    public HouseBlend(){
        setDescription("House Blend Coffee");
    }
    
    @Override
    public double cost() {
        return .98D;
    }

}
package com.zjut.json.decoratorPattern;

/**
 * 装饰者接口
 * 
 * @author json
 *
 * @date 2013-5-6
 */
public abstract class CondimentDecorator extends Beverage {

    public abstract String getDescription();
}
package com.zjut.json.decoratorPattern;

/**
 * @author json
 *
 * @date 2013-5-6
 */
public class Mocha extends CondimentDecorator {
    
    /**被装饰着*/
    private Beverage beverage;

    @Override
    public String getDescription() {
        return beverage.getDescription() + ", Mocha";
    }

    @Override
    public double cost() {
        return beverage.cost() + .20D;
    }

    public Beverage getBeverage() {
        return beverage;
    }

    public void setBeverage(Beverage beverage) {
        this.beverage = beverage;
    }
    
}
package com.zjut.json.decoratorPattern;

/**
 * @author json
 *
 * @date 2013-5-6
 */
public class StarbuzzCoffee {

    public static void main(String[] args){
        Beverage decorated = new Espresson();
        Mocha decorator = new Mocha();
        decorator.setBeverage(decorated);
        System.out.println(decorator.cost());
        
        //双份摩卡
        Mocha doubleDecorator = new Mocha();
        doubleDecorator.setBeverage(decorator);
        System.out.println(doubleDecorator.getDescription() + ": " + doubleDecorator.cost());
    }
}

在这个例子中,装饰者和被装饰着共同继承与抽象组件Beverage,但不同之处在于,装饰者继承抽象组件的是类型,而不是行为,而行为的继承是利用组合,即在具体装饰者对象中存在了一个被装饰者的引用,将被装饰者的行为委托给这个引用。

 

posted on 2013-05-07 00:05  幸福从不迟疑  阅读(269)  评论(0编辑  收藏  举报