demo描述:一个咖啡店,有不同种类的咖啡,现要根据顾客买的咖啡,加的调料来计算要花的钱
demo:
饮品抽象类:
@Data
public abstract class Drink {
//价格
private float price = 0.0f;
//描述
private String des;
//计算价格
public abstract float cost();
}
主体,咖啡:
public class Coffee extends Drink {
@Override
public float cost() {
return super.getPrice();
}
}
具体主体:
public class Espresso extends Coffee {
public Espresso() {
setDes("意大利咖啡");
setPrice(6.0f);
}
}
public class LongBlack extends Coffee {
public LongBlack() {
setDes("美式咖啡");
setPrice(5.0f);
}
}
public class ShortBlack extends Coffee {
public ShortBlack() {
setDes("黑铁咖啡");
setPrice(4.0f);
}
}
装饰者:
public class Decorator extends Drink {
// 继承+组合 重写父类的方法实现功能多样化+包裹被装饰者,累加功能
//组合Drink:要用Drink的子类,
//实现把被装饰者包裹在里边
private Drink obj;
public Decorator(Drink obj) {
this.obj = obj;
}
//通过继承机制实现多样化描述被装饰者的功能
@Override
public float cost() {
return super.getPrice() + obj.cost();
}
@Override
public String getDes() {
return super.getDes() + " " + super.getPrice() ;
}
}
饰品:
public class Milk extends Decorator {
public Milk(Drink obj) {
super(obj);
setDes("牛奶");
setPrice(2.0f);
}
}
public class Chocolate extends Decorator {
public Chocolate(Drink obj) {
super(obj);
setDes("巧克力");
setPrice(3.0f);
}
}
public class Soy extends Decorator {
public Soy(Drink obj) {
super(obj);
setDes("豆浆");
setPrice(1.5f);
}
}
客户端:
public class CoffeeBar {
public static void main(String[] args) {
//先有单品
Drink order = new LongBlack();
System.out.println(order.getDes());
// System.out.println("总价:" + order.cost());
System.out.println("=============");
//开始装饰
order = new Milk(order);
System.out.println(order.getDes() + " ");
// System.out.println("总价:" + order.cost());
System.out.println("=============");
order = new Chocolate(order);
System.out.println(order.getDes());
// System.out.println("总价:" + order.cost());
}
}
demo类图:
类图分析:Drink类让被装饰者与装饰者产生关系,因为两类都要算在总价里。
Drink的作用:管理两者的属性、计费;将属性的get、set分离交,被装饰者(咖啡)负责属性的get,它们是单品,即基础属性,get的时候get的是被装饰了的咖啡的属性(加了***的咖啡的价钱);装饰者调料负责属性的set,每次set的结果要累加,累加到被装饰者上(基础属性)。
Decorator继承Drink,1.通过泛型让Drink能set被装饰者的属性,2.实现装饰者的多样化。Decorator聚合Drink,相当于把被装饰者类包裹在了自己里边,从而可以对被装饰者类的属性进行set并累加。这里巧用了继承机制。
1处可以扩展基础类,2处可扩展装饰类
适用场景:需要动态的将功能 *附加* 到对象上时可以用装饰者模式。注意是附加,不是追加,追加最终还是本类,附加最终是原来类加上附加上的类
总结:类属性读、写分离,让写具有多样化,负责读的类(被装饰者)因为写的累加(被装饰者装饰)实现读到的属性值得多样,累加方式使附加的内容具有顺序,像是穿衣服一样,从里到外一件件的穿。