装饰者模式
定义:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。
举例(咖啡馆订单项目:1)、咖啡种类:Espresso、ShortBlack、LongBlack、Decaf2)、调料(装饰者):Milk、Soy、Chocolate)
被装饰的对象和装饰者都继承自同一个超类
public abstract class Drink { public String description=""; private float price=0f;; public void setDescription(String description) { this.description=description; } public String getDescription() { return description+"-"+this.getPrice(); } public float getPrice() { return price; } public void setPrice(float price) { this.price=price; } public abstract float cost(); }
被装饰的对象,不用去改造。原来怎么样写,现在还是怎么写。
public class Coffee extends Drink { @Override public float cost() { // TODO Auto-generated method stub return super.getPrice(); } }
coffee类的实现
public class Decaf extends Coffee { public Decaf() { super.setDescription("Decaf"); super.setPrice(3.0f); } }
装饰者
装饰者不仅要考虑自身,还要考虑被它修饰的对象,它是在被修饰的对象上继续添加修饰。例如,咖啡里面加牛奶,再加巧克力。加糖后价格为coffee+milk。再加牛奶价格为coffee+milk+chocolate。
public class Decorator extends Drink { private Drink Obj; public Decorator(Drink Obj) { this.Obj = Obj; }; @Override public float cost() { // TODO Auto-generated method stub return super.getPrice() + Obj.cost(); } @Override public String getDescription() { return super.description + "-" + super.getPrice() + "&&" + Obj.getDescription(); } }
装饰者实例化(加牛奶)。这里面要对被修饰的对象进行实例化。
public class Milk extends Decorator { public Milk(Drink Obj) { super(Obj); // TODO Auto-generated constructor stub super.setDescription("Milk"); super.setPrice(2.0f); } }
coffee店:初始化一个被修饰对象,修饰者实例需要对被修改者实例化,才能对具体的被修饰者进行修饰。
public class CoffeeBar { public static void main(String[] args) { Drink order; order = new Decaf(); System.out.println("order1 price:" + order.cost()); System.out.println("order1 desc:" + order.getDescription()); System.out.println("****************"); order = new LongBlack(); order = new Milk(order); order = new Chocolate(order); order = new Chocolate(order); System.out.println("order2 price:" + order.cost()); System.out.println("order2 desc:" + order.getDescription()); } }