- 装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
- 这里提到的动态的将新功能附加到对象和ocp原则,在后面的应用实例上会以代码的形式体现。
场景:我们在点咖啡的时候,会加入一些不同的配料,不同的配料和不同的咖啡会组合出不同的口味的咖啡,如果把这些组合都写成具体的类,就会类爆炸,而且调料的组合也是阶乘级别,不可能具体实现,
核心就是附加,通过递归的思想,完成添加的功能。
代码:
public class SingleFantasy {
public static void main(String[] args) throws CloneNotSupportedException {
Drink order = new LongBlack();
System.out.println("费用1: " + order.cost() +" "+ order.getDes()+" 没有加任何东西");
//加牛奶
order= new Milk(order);
System.out.println("费用2: " + order.cost() +" "+ order.getDes()+" 加入一份牛奶");
//加巧克力
order = new Chocolate(order);
System.out.println("费用2: " + order.cost() +" "+ order.getDes()+" 加入一份巧克力");
}
}
abstract class Drink{
public String des;
private float price = 0.0f;
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public abstract float cost();
}
class Coffee extends Drink{
@Override
public float cost() {
return super.getPrice();
}
}
class Espresso extends Coffee{
public Espresso() {
setDes("意大利卡咖啡");
setPrice(100);
}
}
class LongBlack extends Coffee{
public LongBlack() {
setDes("美式卡咖啡");
setPrice(200);
}
}
class ShortBlack extends Coffee{
public ShortBlack() {
setDes("ShortBlack咖啡");
setPrice(300);
}
}
class Decorator extends Drink{
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
public float cost() {
//当前调料的价格加咖啡的价格
return super.getPrice() + drink.getPrice();
}
@Override
public String getDes() {
return super.getDes() + super.getPrice() + " ## " + drink.getDes() + drink.getPrice();
}
}
class Chocolate extends Decorator{
public Chocolate(Drink drink) {
super(drink);
setDes("巧克力 ");
setPrice(20);
}
}
class Milk extends Decorator{
public Milk(Drink drink) {
super(drink);
super.setDes("牛奶");
super.setPrice(10);
}
}
class Soy extends Decorator{
public Soy(Drink drink) {
super(drink);
setDes("豆浆");
setPrice(1.5f);
}
}
费用1: 200.0 美式卡咖啡 没有加任何东西
费用2: 210.0 牛奶10.0 ## 美式卡咖啡200.0 加入一份牛奶
费用2: 30.0 巧克力 20.0 ## 牛奶10.0 ## 美式卡咖啡200.010.0 加入一份巧克力
简单版代码:
public class SingleFantasy {
public static void main(String[] args) throws CloneNotSupportedException {
Drink mokaCoffee = new MOKACoffee();
System.out.println(mokaCoffee.getName());
mokaCoffee = new addMilk(mokaCoffee);
System.out.println(mokaCoffee.getName());
mokaCoffee = new addSoy(mokaCoffee);
System.out.println(mokaCoffee.getName());
}
}
abstract class Drink{
public String des;
private float price = 0.0f;
public abstract String getName();
}
class MOKACoffee extends Drink{
@Override
public String getName() {
return "MOKACoffee ";
}
}
class Decorator extends Drink{
private Drink drink;
public Decorator(Drink drink) {
this.drink = drink;
}
@Override
public String getName() {
return drink.getName();
}
}
class addMilk extends Decorator{
public addMilk(Drink drink) {
super(drink);
}
@Override
public String getName() {
return "加入了牛奶" + super.getName();
}
}
class addSoy extends Decorator{
public addSoy(Drink drink) {
super(drink);
}
@Override
public String getName() {
return "加入了豆浆" + super.getName();
}
}
MOKACoffee
加入了牛奶MOKACoffee
加入了豆浆加入了牛奶MOKACoffee