装饰者模式定义:
装饰者模式:动态地将新功能附加到对象上,在对象能扩展方面,它比继承更有弹性,装饰者模式也体现了开闭原则。
装饰者模式原理:
装饰者模式就像打包一个快递。
主体:比如瓷器、衣服。(component :被装饰者)
包装:比如用安全性好的盒子来装瓷器避免受到磕碰而损坏。(decorator:装饰者)
那么在下面的案例中:
component即顾客要饮用的咖啡。
concrete component就是一个个的具体的单品咖啡,如Enpresso等。
decorator即为加在咖啡中用来调节口味的调料。
concrete decorator一种种具体的调料,如milk等。
UML图如下:
引用案例:咖啡订单项目
1、咖啡种类:LongBlack Espresso ShortBlack
2、调料:milk soy chocolate
3、要求在扩展新的咖啡种类时,具有良好的扩展性,改动方便,维护方便
4、计算咖啡的费用:客户可以单点咖啡,也可以向咖啡中添加调料。
装饰者模式:先点一份单品咖啡,再加入一份牛奶,再加入一份巧克力,再加入一份巧克力的结构组成是这样的。有点类似于算法中的递归。
component:
package Coffee; //前面所说的抽象类 component public abstract class Drink { public String des; private double price=0.0; public String getDes() { return des; } public void setDes(String des) { this.des = des; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } //计算费用的抽象方法 //交给子类来实现 public abstract double cost(); }
package Coffee; public class Coffee extends Drink{ @Override public double cost() { // TODO Auto-generated method stub return super.getPrice(); } }
具体的component:
package Coffee; public class ShortBlack extends Coffee{ public ShortBlack() { setDes("ShortBlack"); setPrice(4.0); } } package Coffee; public class LongBlack extends Coffee{ public LongBlack() { setDes("LongBlack"); setPrice(5.0); } } package Coffee; public class Espresso extends Coffee{ public Espresso() { setDes("意大利"); setPrice(6.0); } }
decorator:
package Coffee; //装饰类 public class Decorator extends Drink{ private Drink obj; public Decorator(Drink obj) { this.obj=obj; } //进行费用的叠加计算,递归的计算 @Override public double cost() { return this.getPrice()+obj.cost(); } public String getDes() { return this.des+" "+this.getPrice()+" "+obj.getDes(); } }
具体的decorator:
package Coffee; //具体的Decorator public class Chocolate extends Decorator{ public Chocolate(Drink obj) { super(obj); setDes("巧克力"); setPrice(3.0); } } package Coffee; public class Milk extends Decorator{ public Milk(Drink obj) { super(obj); setDes("牛奶"); setPrice(2.0); } } package Coffee; public class Soy extends Decorator{ public Soy(Drink obj) { super(obj); setDes("豆浆"); setPrice(1.5); } }
咖啡店测试用例:
package Coffee; public class CoffeeBar { public static void main(String[] args) { //先单点一份LongBlack咖啡 Drink order = new LongBlack(); System.out.println(order.getDes()); System.out.println("此时总花费是:"+order.cost()); //再往咖啡中加入一份牛奶 order = new Milk(order); System.out.println(order.getDes()); System.out.println("此时总花费是:"+order.cost()); //在加入牛奶的基础上加入巧克力 order = new Chocolate(order); System.out.println(order.getDes()); System.out.println("此时总花费是:"+order.cost()); //在加入牛奶和巧克力的基础之上再加入一份巧克力 order = new Chocolate(order); System.out.println(order.getDes()); System.out.println("此时总花费是:"+order.cost()); } }
整体的UML类图:
如有错误,还请大家指出,我会虚心改正。