一,何为装饰模式?
其目的是包装一个目标对象,从而可以在运行时动态添加新的职责。每个装饰器都可以包装另一个装饰器,这样从理论上来说可以对目标对象进行无限次的修饰
二,用普通代码实现装饰模式
//Order接口
public interface Order {
public double getPrice();
public String getLabel();
}
//被装饰的类要实现Order接口
public class Pizza implements Order {
private String label;
private double price;
public Pizza(String label, double price) {
this.label = label;
this.price = price;
}
public double getPrice() {
return this.price;
}
public String getLabel() {
return this.label;
}
}
如下用代码创建了一个披萨
Order pizza = new Pizza("newPizza",10);
接下来需要创建一个装饰器,它会通过额外的配料来装饰披萨。这里使用了一个抽象类,这样具体类就不必实现接口中所有的业务方法了。抽象装饰器会创建一个可供其它装饰器继承的蓝图
抽象装饰器
ublic abstract class Extra implements Order {
protected Order order;
protected String label;
protected double price;
public Extra(String label, double price, Order order) {
this.label = label;
this.price = price;
this.order = order;
}
// Price can be a big issue, so delegate this to concrete implementation
public abstract double getPrice();
// Should be okay to provide standard labeling
public String getLabel() {
return order.getLabel() + ", " + this.label;
}
}
创建具体装饰器1
public class RegularExtra extends Extra {
public RegularExtra(String label, double price, Order order) {
super(label, price, order);
}
public double getPrice() {
return this.price + order.getPrice();
}
}
创建具体装饰器2
public class NoCostExtra extends Extra {
public NoCostExtra(String label, double price, Order order) {
super(label, price, order);
}
public double getPrice() {
return order.getPrice();
}
}
创建具体装饰器3
public class DoubleExtra extends Extra {
public DoubleExtra(String label, double price, Order order) {
super(label, price, order);
}
public double getPrice() {
return (this.price*2)+order.getPrice();
}
public String getLabel() {
return order.getLabel()+ ", Double " + this.label;
}
}
测试
Order fourSeasonsPizza = new Pizza("Four Seasons Pizza", 10);
fourSeasonsPizza = new RegularExtra("Pepperoni", 4, fourSeasonsPizza );
fourSeasonsPizza = new DoubleExtra("Mozzarella", 2, fourSeasonsPizza );
fourSeasonsPizza = new NoCostExtra("Chili", 2, fourSeasonsPizza );
System.out.println(fourSeasonsPizza.getPrice());
System.out.println(fourSeasonsPizza.getLabel());