咖啡问题
现需要完成一个咖啡下单的问题:
- 咖啡种类:Espresso、ShortBlack、LongBlack、Decaf
- 调料:Milk、Soy、Chocolate
- 要求在扩展新的咖啡种类时,具有良好的扩展性,改动方便
- 使用OO来计算不同种类咖啡的费用,客户可以点单品咖啡,也可以单品咖啡+调料组合
装饰者模式
基本介绍
- 装饰者模式能够动态的将新的功能附加到对象上,在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则
- 装饰者模式装饰者模式就像打包一个快递,其中包含主体(即打包的物品);以及包装(快递包装外壳);一个主体可以由多个包装嵌套装饰
装饰者模式解决咖啡问题
/***
* @author shaofan
* @Description 装饰者模式解决咖啡问题
*/
public class CoffeeBar {
public static void main(String[] args) {
// 一份牛奶,两份巧克力的Espresso
// 不带任何配料的咖啡,装饰者中的主体
Drink order = new Espresso();
// 加入一份牛奶,使用牛奶装饰主体
order = new Milk(order);
// 加入一份巧克力,使用巧克力再次装饰
for(int i=0;i<2;i++){
order = new Chocolate(order);
}
System.out.println(order.cost());
System.out.println(order.getDescription());
}
}
abstract class Drink{
private String desc;
private double price;
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
abstract double cost();
abstract String getDescription();
}
class Decorator extends Drink{
private Drink drink;
public Decorator(Drink drink){
this.drink = drink;
}
@Override
double cost() {
return super.getPrice()+drink.cost();
}
@Override
String getDescription() {
return drink.getDescription()+"+"+super.getDesc();
}
}
class Coffee extends Drink{
@Override
double cost() {
return super.getPrice();
}
@Override
String getDescription() {
return getDesc();
}
}
class Espresso extends Coffee{
private final String DESC = "Espresso";
private final double PRICE = 5.0;
public Espresso(){
super.setDesc(DESC);
super.setPrice(PRICE);
}
}
class ShortBlack extends Coffee{
private final String DESC = "ShortBlack";
private final double PRICE = 5.0;
public ShortBlack(){
super.setDesc(DESC);
super.setPrice(PRICE);
}
}
class Chocolate extends Decorator{
private final String DESC = "Chocolate";
private final double PRICE = 1.0;
public Chocolate(Drink drink){
super(drink);
super.setDesc(DESC);
super.setPrice(PRICE);
}
}
class Milk extends Decorator{
private final String DESC = "Milk";
private final double PRICE = 2.0;
public Milk(Drink drink){
super(drink);
super.setDesc(DESC);
super.setPrice(PRICE);
}
}
源码分析
在Java的IO中,FilterInputStream就是一个装饰者
它的内部组合了一个InputStream,对FileInputStream、StrintgBufferInputStream、ByteArrayInputStream这些主体进行装饰,提供一些额外的功能