有一家咖啡店,你想喝杯咖啡,于是你走进咖啡店,咖啡店有主体浓缩咖啡、黑咖啡、深培咖啡,当然,咖啡中也可以加一些调料:豆浆、摩卡、奶泡等。每种咖啡或者调料,价格都不一样,你可以单点一杯咖啡,也可以点一杯咖啡加上自己喜欢的调料。那么价格怎么算呢,我们可以通过装饰者模式试试,先看一下咖啡调料UML类图:
看一下价格计算过程,此图来自《Head First 设计模式》:
再看看java代码:
/**
* 咖啡抽象类,被装饰者
*/
public abstract class Beverage {
String description = "咖啡";
public String getDescription() {
return description;
}
public abstract double cost();
}
/**
* 调料抽象类,就是装饰者类
*/
public abstract class CondimentDecorator extends Beverage{
public abstract String getDescription();
}
三种不同的咖啡主体:
/**
* 浓缩咖啡
*/
public class Espresso extends Beverage {
public Espresso() {
description = "浓缩咖啡";
}
public double cost() {
return 1.99;
}
}
/**
* 黑咖啡
*/
public class HoseBlend extends Beverage {
public HoseBlend() {
description = "黑咖啡";
}
public double cost() {
return 0.99;
}
}
/**
* 深焙咖啡
*/
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "深焙咖啡";
}
public double cost() {
return 0.19;
}
}
三种不同的调料:
/**
* 摩卡
*/
public class Mocha extends CondimentDecorator{
private Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", 摩卡";
}
public double cost() {
return 0.20 + beverage.cost();
}
}
/**
* 豆浆
*/
public class Soy extends CondimentDecorator {
private Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", 豆浆";
}
public double cost() {
return 0.23 + beverage.cost();
}
}
/**
* 奶泡
*/
public class Whip extends CondimentDecorator {
private Beverage beverage;
public Whip(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", 奶泡";
}
public double cost() {
return 0.69 + beverage.cost();
}
}
最后看一下测试类及结果:
public class StrabuzzCoffee {
public static void main(String[] args) {
//单点一杯浓缩咖啡
Beverage beverage = new Espresso();
System.out.println(beverage.getDescription() + ", $" + beverage.cost());
System.out.println("----------------------------------------------");
//一杯双倍摩卡一份奶泡的黑咖啡
Beverage beverage2 = new HoseBlend();
beverage2 = new Mocha(beverage2);
beverage2 = new Mocha(beverage2);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + ", $" + beverage2.cost());
System.out.println("----------------------------------------------");
//一杯调料为豆浆、摩卡、奶泡的深焙咖啡
Beverage beverage3 = new DarkRoast();
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
System.out.println(beverage3.getDescription() + ", $" + beverage3.cost());
System.out.println("----------------------------------------------");
}
}
结果: