三、装饰者模式(Decoator-patterns)
咖啡厅订单系统项目:
1)咖啡种类:Espresso、ShortBack、LongBack|、Decaf
2)调料:Milk、Soy、Chocolate
如果此时新加一种调料,或者新加一种原料,那么组合起来就会导致类的爆炸,导致不易维护。
那么此时可以用一个超类将所有类型的原料和调料放进去。
那么如果新加原料或者调料那么直接可以在 Drink中定义局部变量,然后set这个变量即可添加。
那么在计算费用的时候,比如说在ShortBlack中 的cost()方法中我们可以循环判断出是否有某种原料,又因为每种原料有自己的价格,所以此时,将每种原料的cost相加即可。这样就避免了类的爆炸。
但是如果想要删除调料种类就比较麻烦。
装饰者模式就像打包一个快递,那么主体就相当于我们包裹中的东西比如说
衣服,那么包装就是:塑料泡沫,填充纸板。
抽象构建 Component:给出一个抽象接口,以规范准备接受附加责任的对象。也就是说主体,就是你装饰的主体可以扩展成具体的东西 比如说要包装的东西。
具体构建 ConcreteComponent :定义一个将要接受附加责任的类。用来具体被包装的物体。
装饰角色Decorator:持有一个构件(Component)对象的实例,并定义一个与抽象构建接口一致的接口就是装饰的类,比如说塑料泡沫。
具体装饰(Concrete Decorator)角色:负责交给构建对象“贴上”附加的责任。
装饰者模式:动态的将新功能怎加到对象上,在对象功能扩展方面它比继承更有弹性。
用牛奶来包装LongBack 然后再用巧克力包装。分别计算费用。
package Decoator;
public abstract class Drink {
public String description="";
private float price=0f;
public void setDescription(String description) {
this.description = description;
}
public float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
public abstract float cost();
public String getDescription() {
// TODO Auto-generated method stub
return description+"-"+this.getPrice();
}
}
package Decoator.concrete;
import Decoator.Drink;
public class Coffe extends Drink {
@Override
public float cost() {
return super.getPrice();
}
}
package Decoator.concrete;
public class Decaf extends Coffe {
public Decaf() {
super.setDescription("Decaf");
super.setPrice(3.0f);
}
}
package Decoator.concrete;
public class Espresso extends Coffe {
public Espresso() {
super.setDescription("Espresso");
super.setPrice(5.0f);
}
}
package Decoator.decorator;
import Decoator.Drink;
public class Decorator extends Drink {
private Drink Obj;
public Decorator(Drink Obj) {
this.Obj=Obj;
}
@Override
public float cost() {
return super.getPrice()+Obj.cost();
}
@Override
public String getDescription() {
return super.description+"--"+super.getPrice()+"&&"+Obj.getDescription();
}
}
package Decoator.decorator;
import Decoator.Drink;
public class Chocolate extends Decorator {
public Chocolate(Drink Obj) {
super(Obj);
super.setDescription("Chocolate");
super.setPrice(6.0f);
}
}
package Decoator.decorator;
import Decoator.Drink;
public class Milk extends Decorator {
public Milk(Drink Obj) {
super(Obj);
super.setDescription("Milk");
super.setPrice(7.0f);
}
}
package Decoator.decorator;
import Decoator.Drink;
public class Soy extends Decorator {
public Soy(Drink Obj) {
super(Obj);
super.setDescription("Soy");
super.setPrice(8.0f);
}
}
package Decoator;
import Decoator.concrete.Decaf;
import Decoator.decorator.Soy;
public class CoffeeBar {
public static void main(String[] args) {
Drink order;
order = new Decaf();
order = new Soy(order);
System.out.println(order.getDescription() + order.getPrice());
}
}