装饰者模式 动态的将责任附加到对象上面。若要扩展功能,装饰者提供了比继承更有弹性的替代方案
1.装饰者与被装饰者对象有相同的父类
2.你可以用一个或者多个装饰者包装一个对象
3.因为装饰者与被装饰者具有相同的父类,所以在任何需要被包装对象的场合,都可以用装饰者代替
4.对象可以在任何时候被装饰,所以可以在运行时动态地,不限量地用你喜欢的装饰者来装饰对象
装饰者模式类图
下面要完成一个咖啡店的订购,顾客点一杯咖啡,可以选择咖啡里面什么都不加,或者加牛奶,加摩卡等等。。。根据不同的需求可以计算出饮料的价格
package com.wdf.decorate;
/*
* 饮料类
* */
public abstract class Beverage {
String description="Unknow Beverage";
public String getDescription(){
return description;
}
public abstract double cost();
}
package com.wdf.decorate;
/*
* 抽象的装饰者基类
* */
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
package com.wdf.decorate;
/*
* 浓缩咖啡
* */
public class Espresso extends Beverage{
public Espresso() {
description="Espresso";
}
@Override
public double cost() {
return 1.99;
}
}
package com.wdf.decorate;
/*
* 深培咖啡
* */
public class DarkRoast extends Beverage{
public DarkRoast() {
description="DarkRoast";
}
@Override
public double cost() {
return 0.98;
}
}
package com.wdf.decorate;
/*
* 调料摩卡
* */
public class Mocha extends CondimentDecorator{
Beverage beverage;//要被装饰的对象引用
public Mocha(Beverage beverage) {
this.beverage=beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+",Mocha";
}
@Override
public double cost() {
return 0.20+beverage.cost();
}
}
package com.wdf.decorate;
public class Test {
public static void main(String[] args) {
/*点一杯浓缩咖啡,什么都不加*/
Beverage beverage=new Espresso();
System.out.println(beverage.getDescription()+"$"+beverage.cost());
/*点一杯深培咖啡,加双倍摩卡*/
Beverage beverage2=new DarkRoast();
beverage2=new Mocha(beverage2);
beverage2=new Mocha(beverage2);
System.out.println(beverage2.getDescription()+"$"+beverage2.cost());
}
}
结果:
Espresso$1.99
DarkRoast,Mocha,Mocha$1.38