动态地将责任附加到对象上。想要扩展功能,装饰者提供有别于继承的另一种选择。
观察者模式类图
场景解读
一杯咖啡可能要加配料,要加摩卡配料,还是加牛奶,还是两者一起加,这样的咖啡价钱会根据变化不一样,如果不用装饰者模式,很难扩展使结构整洁。如这样加到到某个咖啡类里。
这样的结构且复杂,不利于扩展。
Beverage 饮料类
Espresso 浓咖啡
HouseBlend 首选咖啡(星巴克咖啡名)
CondimentDecorator 调味料抽象类
Milk 牛奶
Mocha 摩卡配料
代码展示
饮料类
饮料类抽象接口
Beverage
package decoratoMode.yinliaomodel;
/**
* 饮料类
*/
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
/**
* 花费
* @return
*/
public abstract double cose();
}
Espresso 浓咖啡
package decoratoMode.yinliaomodel;
/**
* 浓咖啡
*/
public class Espresso extends Beverage {
public Espresso() {
description = "espresso";
}
@Override
public double cose() {
return 1.99;
}
}
HouseBlend 首选咖啡(星巴克咖啡名)
package decoratoMode.yinliaomodel;
/**
* 首选咖啡(星巴克咖啡名)
*/
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "houseBlend";
}
@Override
public double cose() {
return .87;
}
}
配料类
接口
CondimentDecorator 调味料抽象类
package decoratoMode.tiaoweiliaoModel;
import decoratoMode.yinliaomodel.Beverage;
/**
* 调味料抽象类
*/
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
Milk
package decoratoMode.tiaoweiliaoModel;
import decoratoMode.yinliaomodel.Beverage;
/**
* 牛奶
*/
public class Milk extends CondimentDecorator {
Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+" add milk";
}
@Override
public double cose() {
return beverage.cose()+0.45;
}
}
Mocha
package decoratoMode.tiaoweiliaoModel;
import decoratoMode.yinliaomodel.Beverage;
/**
* 摩卡配料
*/
public class Mocha extends CondimentDecorator {
Beverage beverage ;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
@Override
public String getDescription() {
return beverage.getDescription()+" add Mocha";
}
@Override
public double cose() {
return beverage.cose()+0.3;
}
}
测试类
package decoratoMode.test;
import decoratoMode.tiaoweiliaoModel.Milk;
import decoratoMode.tiaoweiliaoModel.Mocha;
import decoratoMode.yinliaomodel.Beverage;
import decoratoMode.yinliaomodel.Espresso;
import org.junit.Test;
public class StarbuzzCoffee {
@Test
public void test1(){
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription()+"$"+beverage.cose());
//装饰
beverage = new Mocha(beverage);
beverage = new Milk(beverage);
System.out.println(beverage.getDescription()+"$"+beverage.cose());
}
}
输出结果
espresso$1.99
espresso add Mocha add milk$2.74
总结:
总的来说,挺神奇的,一层包着一层,
设计原则:类应该对扩展开放,对修改关闭
代码github连接
https://github.com/sky5cai/DesignModeTest