一、问题描述
为星巴兹咖啡连锁店设计饮料菜单,咖啡可加的调料有豆浆、牛奶、摩卡等。可在咖啡的基础上加入不同的调料,星巴兹会根据所加的调料收取不同的费用,要注意到,以后可能有新的调料被加入进来供顾客选择。并且本店现有DarkRoast(深焙)、HouseBlend(综合)、Decaf(低咖啡因)及Espresso(浓咖啡)四种类型的咖啡,而且以后可能会添加新的咖啡种类。
使用装饰者模式,四种咖啡为具体组件,调料为具体装饰者。
二、类图
三、代码实现
1.抽象组件角色:Beverage(饮料)
public abstract class Beverage {
String description = "Unknown Beverage";
public String getDescription() {
return description;
}
public abstract double cost();
}
2.具体组件角色:四种类型的咖啡
(1)DarkRoast
public class DarkRoast extends Beverage {
public DarkRoast() {
description = "Dark Roast Coffee";
}
public double cost() {
return .99;
}
}
(2)Decaf
public class Decaf extends Beverage {
public Decaf() {
description = "Decaf Coffee";
}
public double cost() {
return 1.05;
}
}
(3)Espresso
public class Espresso extends Beverage {
public Espresso() {
description = "Espresso";
}
public double cost() {
return 1.99;
}
}
(4)HouseBlend
public class HouseBlend extends Beverage {
public HouseBlend() {
description = "House Blend Coffee";
}
public double cost() {
return .89;
}
}
3.装饰者角色:CondimentDecorator
public abstract class CondimentDecorator extends Beverage {
public abstract String getDescription();
}
4.具体装饰者:各种调料
(1)Milk
public class Milk extends CondimentDecorator {
Beverage beverage;
public Milk(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Milk";
}
public double cost() {
return .10 + beverage.cost();
}
}
(2)Mocha
public class Mocha extends CondimentDecorator {
Beverage beverage;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Mocha";
}
public double cost() {
return .20 + beverage.cost();
}
}
(3)Whip
public class Whip extends CondimentDecorator {
Beverage beverage;
public Whip(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Whip";
}
public double cost() {
return .10 + beverage.cost();
}
}
(4)Soy
public class Soy extends CondimentDecorator {
Beverage beverage;
public Soy(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription() + ", Soy";
}
public double cost() {
return .15 + beverage.cost();
}
}
5.测试
public class StarbuzzCoffee
{
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);
beverage2 = new Whip(beverage2);
System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
Beverage beverage3 = new HouseBlend();
beverage3 = new Soy(beverage3);
beverage3 = new Mocha(beverage3);
beverage3 = new Whip(beverage3);
System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
}
}
四、其他
对于抽象构件角色是由抽象类还是接口实现,以及是否需要实现装饰者角色等,这要根据具体的需要选择。变化的需求促使我们不断对系统进行更改和优化。
转载请注明出处:http://blog.youkuaiyun.com/jialinqiang/article/details/8882993