定义
装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则(ocp)
案例
咖啡种类/单品咖啡: Espresso( 意大利浓咖啡)、ShortBlack、 LongBlack(美 式咖啡)、Decaf(无因咖啡)
调料: Milk、 Soy(豆浆)、 Chocolate
要求在扩展新的咖啡种类时,具有良好的扩展性、改动方便、维护方便
使用00的来计算不同种类咖啡的费用:客户可以点单品咖啡,也可以单品咖啡+调料组合。
方法一:
方法二:
装饰器
客户点单的时候一般会在咖啡里面加配料,也就是需要用配料给咖啡进行装饰,装饰器模式实现如下;
1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。
装饰器模式下订单——2份巧克力+1份牛奶的LongBlack
说明
- Milk包含了LongBlack
- 一 份Chocolate包 含了(Milk+LongBlack)
- 一份Chocolate包含了(Chocolate+ Milk+LongBlack)
4)这样不管是什么形式的单品咖啡+调料组合,通过递归方式可以方便的组合和维护。
实现
package com.xhl.Decorator;
public abstract class Drink {
private 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();
}
package com.xhl.Decorator;
public class Coffee extends Drink {
@Override
public float cost() {
// TODO Auto-generated method stub
return super.getPrice();
}
}
package com.xhl.Decorator;
public class Espresso extends Coffee {
public Espresso() {
setDes("意大利咖啡");
setPrice(2.2f);
}
}
package com.xhl.Decorator;
public class ShortBlack extends Coffee {
public ShortBlack() {
setDes("ShortBlack");
setPrice(1.5f);
}
}
package com.xhl.Decorator;
public class LongBlack extends Coffee {
public LongBlack() {
setDes("LongBlack");
setPrice(2.0f);
}
}
package com.xhl.Decorator;
public class DeCaf extends Coffee {
public DeCaf() {
setDes("无因咖啡");
setPrice(1.0f);
}
}
package com.xhl.Decorator;
public class Decorator extends Drink {
private Drink obj;
public Decorator(Drink obj) {
super();
this.obj = obj;
}
@Override
public float cost() {
// TODO Auto-generated method stub
return super.getPrice()+obj.cost();
}
@Override
public String getDes() {
// TODO Auto-generated method stub
return super.getDes()+"&&"+obj.getDes();
}
}
package com.xhl.Decorator;
public class Chocolate extends Decorator {
public Chocolate(Drink obj) {
super(obj);
setDes("巧克力");
setPrice(3.0f);
}
}
package com.xhl.Decorator;
public class Mike extends Decorator {
public Mike(Drink obj) {
super(obj);
setDes("牛奶");
setPrice(1.0f);
}
}
package com.xhl.Decorator;
public class Soy extends Decorator {
public Soy(Drink obj) {
super(obj);
setDes("豆浆");
setPrice(1.5f);
}
}
package com.xhl.Decorator;
public class CofferBarDemo {
public static void main(String[] args) {
// TODO Auto-generated method stub
Drink order = new LongBlack();
System.out.println("LongBlack 费用:"+order.cost());
System.out.println("LongBlack 描述:"+order.getDes());
order = new Mike(order);
System.out.println("加入一份牛奶 费用:"+order.cost());
System.out.println("加入一份牛奶 描述:"+order.getDes());
order = new Chocolate(order);
System.out.println("加入一份巧克力 费用:"+order.cost());
System.out.println("加入一份巧克力 描述:"+order.getDes());
order = new Chocolate(order);
System.out.println("2份巧克力+1份牛奶的LongBlack 费用:"+order.cost());
System.out.println("2份巧克力+1份牛奶的LongBlack 描述:"+order.getDes());
System.out.println("=====================================");
Drink order2 = new Mike(new DeCaf());
System.out.println("无因咖啡+牛奶 费用:"+order2.cost());
System.out.println("无因咖啡+牛奶 描述:"+order2.getDes());
}
}
装饰者模式在JDK应用
Java的IO结构,FilterInputStream 就是一个装饰者