一、概述
- 装饰者模式:动态地将新功能附加到对象上。在对象功能拓展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
- 装饰者模式就像打包一个快递,主体是Component;包装是Decorator;ConcreteComponent是具体的主体
- 感觉这种方法,很像代理模式,只是这是静态的操作,局限性比较大
二、装饰者模式解决咖啡订单问题
- 设置一个抽象基类
Drink
,包含该单品的价格price
及描述desc
属性。设置一个抽象方法,cost()
public abstract class Drink {
private String desc;
private double price;
public Drink() {
}
public Drink(String desc, double price) {
this.desc = desc;
this.price = 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;
}
public abstract double cost();
public abstract String getDescription();
}
- 抽象基类
Coffee
继承Drink
,cost()
表示当前饮品的价格,就是当前类的price
属性,即啥都没加;getDesccription()
为描述整个饮品的组合及价格,目前只有单品饮品及价格
public abstract class Coffee extends Drink {
public Coffee() {
}
public Coffee(String desc, double price) {
super(desc, price);
}
@Override
public double cost() {
return super.getPrice();
}
@Override
public String getDescription() {
return super.getDesc() + " " + super.getPrice() + " ";
}
}
- 具体的咖啡实现类,在构造器中设置好该单品的价格及描述
public class Decaf extends Coffee {
public Decaf() {
super("Decaf", 6.0);
}
}
- 抽象基类
Decorator
,通过继承和组合的方式与Drink
发生关联。即它自身就是一杯咖啡,内含一个属性为,加此次原料前的咖啡。cost()
等于当前单品的价格price
加上属性Drink
的cost()
,getDesccription()
同理
public abstract class Decorator extends Drink {
Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
public Decorator(String desc, double price, Drink drink) {
super(desc, price);
this.drink = drink;
}
@Override
public double cost() {
return this.getPrice() + drink.cost();
}
@Override
public String getDescription() {
return drink.getDescription() + super.getDesc() + " " + super.getPrice() + " ";
}
}
- 具体的加料实现类,在构造器中设置好该单品的价格及描述,并接受需要被包装的
Drink()
public class Milk extends Decorator {
public Milk(Drink drink) {
super("Milk", 2.0, drink);
}
}
public class Client {
public static void main(String[] args) {
Drink shortBlack = new ShortBlack();
System.out.println(shortBlack.getDescription());
System.out.println(shortBlack.cost());
Chocolate chocolate = new Chocolate(shortBlack);
System.out.println(chocolate.getDescription());
System.out.println(chocolate.cost());
Milk milk = new Milk(chocolate);
System.out.println(milk.getDescription());
System.out.println(milk.cost());
Chocolate chocolate1 = new Chocolate(milk);
System.out.println(chocolate1.getDescription());
System.out.println(chocolate1.cost());
}
}