背景需求
星巴克咖啡订单项目
- 咖啡种类:意大利浓咖啡(Espresso),美式咖啡(LongBlack),无因咖啡(Decaf)
- 调料:Milk、Soy、Chocolate
- 要求在拓展新的咖啡种类时,具有良好的拓展性,改动方便,维护方便
- 计算不同种类咖啡的费用:客户可以单品咖啡,也可以单品咖啡+调料组合
定义
装饰者模式:动态的将新功能附加到对象上。在对象功能拓展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)。
代码示例
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 15:55
* @Desc
*/
public abstract class Drink {
private String desc;
private int price;
abstract int cost();
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 16:06
* @Desc 咖啡
*/
public class Coffee extends Drink{
@Override
int cost() {
return super.getPrice();
}
}
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 15:57
* @Desc 意大利浓咖啡
*/
public class Espresso extends Coffee{
public Espresso() {
setDesc("意大利浓咖啡");
setPrice(10);
}
@Override
int cost() {
return super.getPrice();
}
}
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 15:59
* @Desc 无因咖啡
*/
public class Decaf extends Coffee{
public Decaf() {
setDesc("无因咖啡");
setPrice(15);
}
@Override
int cost() {
return super.getPrice();
}
}
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 16:00
* @Desc 装饰者
*/
public class Decorator extends Drink{
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
int cost() {
return super.getPrice() + drink.cost();
}
@Override
public String getDesc(){
return super.getDesc() + "" + super.getPrice() + "&&" + drink.getDesc();
}
}
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 16:05
* @Desc 调料:牛奶
*/
public class Milk extends Decorator{
public Milk(Drink drink) {
super(drink);
setDesc("牛奶");
setPrice(3);
}
}
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 16:04
* @Desc 调料:巧克力
*/
public class Chocolate extends Decorator{
public Chocolate(Drink drink) {
super(drink);
setDesc("巧克力");
setPrice(5);
}
}
package com.zjb.design.decorator;
/**
* @Author Kim
* @Date 2022/5/2 16:06
* @Desc
*/
public class CoffeeBar {
public static void main(String[] args) {
Drink order = new Decaf();
System.out.println("一份无因咖啡的费用:"+order.cost());
order = new Milk(order);
System.out.println("一份无因咖啡加一份牛奶的费用:"+ order.cost());
order = new Chocolate(order);
System.out.println("一份无因咖啡加一份牛奶加一份巧克力的费用:"+ order.cost());
}
}