一,定义
动态的将新功能附加到对象上。在对新功能扩展方面,他比继承更具有弹性
装饰者模式也体现了开闭原则
顾名思义,装饰者模式就像一个包装一个快递一样的包装盒
二,以饮料为例,来讲解什么是装饰者模式
假设有一个饮料drink抽象类,实现coffee咖啡与不同点心的搭配问题,如上图。
以面向对象的思想。肯定是每个对象为一个类。假设每个人都是点一份咖啡和一些点心时。假设我们就以简单的组合的方式,那么就肯定有n种组合,并且根据种类的不同,以及份数的不同,就更加的增加了代码的臃肿性
接下来就需要使用到装饰者模式了,我们就将这个点心作为被装饰者,那么就只需要考虑点心了。因此给点心一个装饰类,比如需要一份咖啡和一份牛奶和一份巧克力,如下图,只需要层层包装即可
三,代码
drink类
public 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();
}
coffee类
public class Coffee extends Drink {
@Override
public float cost() {
return super.getPrice();
}
}
coffee子类
public class ShortCoffee extends Coffee{
public ShortCoffee(){
setDes("英式咖啡");
setPrice(4.0f);
}
}
public class LongBlack extends Coffee {
public LongBlack(){
setDes("美式咖啡");
setPrice(3.0f);
}
}
public class Espresso extends Coffee {
public Espresso(){
setDes("意大利咖啡");
setPrice(6.0f);
}
}
装饰者类 Decorator 类
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 getDes() {
return super.des + " " + super.getPrice()+ "&&" + obj.getDes();
}
}
点心类
豆浆类 Soy
public class Soy extends Decorator {
public Soy(Drink obj) {
super(obj);
setDes("豆浆");
setPrice(1.5f);
}
}
牛奶类 Milk
public class Milk extends Decorator {
public Milk(Drink obj) {
super(obj);
setDes("牛奶");
setPrice(2.0f);
}
}
巧克力类 chocolate
public class Chocolate extends Decorator {
public Chocolate(Drink obj) {
super(obj);
setDes("巧克力");
setPrice(3.0f); //调味品价格
}
}
四,测试类 CofferBar
public class CofferBar {
public static void main(String[] args) {
//1,先点一份LongBlack
Drink order = new LongBlack(); //费用一
System.out.println(order.cost());
//2,加入一份牛奶
order = new Milk(order);
System.out.println(order.cost());
System.out.println(order.getDes());
//3,加入一份巧克力
order = new Chocolate(order);
System.out.println(order.cost());
System.out.println(order.getDes());
}
}
如图
这样的话就完美的解决了咖啡和点心的组合了。当然由于每个人是点一份咖啡和多份点心的,因此需要不同的咖啡就需要创建不同的的 coffee 对象即可了!