装饰者模式

模式定义

动态的给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比子类更加灵活

类图定义

示例

星巴兹咖啡订单系统,购买咖啡时根据顾客不同的咖啡类型,比如深度烘培或者混合咖啡和不同的原料比如摩卡,豆浆等原料计算咖啡的价格。按照正常思路设计首先有一个饮料的父类,提供cost计算价格的方法,其他不同的原料不同类型的咖啡都继承这个父类,这样设计出来的子类会随着原料的不停增加变的庞大无比。所以可以通过装饰者模式不同类型的咖啡用不同的原料进行装饰,比如摩卡的混合咖啡,使用摩卡对象去装饰混合咖啡对象,这样会有极大的灵活性。

/**
 * 饮料类
 *
 * @author Colin
 * @create 2018-03-20
 **/
public abstract class Beverage {
    String description="Unknown Beverage";

    public String getDescription(){
        return description;
    }
    public abstract double cost();
}

/**
 * 混合搅拌咖啡
 *
 * @author Colin
 * @create 2018-03-20
 **/
public class HouseBlend extends Beverage {
    public HouseBlend(){
        this.description="混合咖啡";
    }
    @Override
    public double cost() {
        return  1.5;
    }
}

/**
 * 调料装饰者类
 *
 * @author Colin
 * @create 2018-03-20
 **/
public abstract class CondimentDecorator extends Beverage {

    @Override
    public abstract String getDescription();
}

/**
 * 摩卡
 *
 * @author Colin
 * @create 2018-03-20
 **/
public class Mocha extends CondimentDecorator {
    private Beverage beverage;
    public Mocha(Beverage beverage){
        this.beverage=beverage;
    }
    @Override
    public String getDescription() {
        return  beverage.getDescription()+",摩卡";
    }

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

/**
 * 装饰者测试类
 *
 * @author Colin
 * @create 2018-03-20
 **/
public class DecoratorTest {

    @Test
    public void testDecoraor(){

        Beverage espressso=new Espressso();
        espressso=new Mocha(espressso);
        espressso=new Whip(espressso);
        System.out.println("咖啡:"+espressso.getDescription()+",价格:"+espressso.cost());

    }
}


总结

  • 装饰者模式应用场景:当系统需要新的功能的时候,是向旧的类中添加新的代码,这些新加的代码通常装饰了原有类的核心职责或行为,如果在主类中增加新的字段,新的方法,新的逻辑从而增加了主类的复杂度,而这些新加的东西仅仅是为了满足一些只在特定情况下才会执行的特殊行为的需要,而装饰者模式提供了非常好的解决方案,它把每个要装饰的功能放在单独的类中,并让这个类包装它需要装饰的对象,因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择的按顺序的使用装饰功能包装对象。有效的把类的核心功能和装饰功能区分开了,而且可以去除相关类中的重复的装饰逻辑。

涉及的原则

  • 开闭原则:类应该对扩展开放,对修改关闭

posted on 2018-04-08 20:53  colinzh  阅读(91)  评论(0)    收藏  举报

导航