I. Decorator 作用
在一些情况下,一个类需要加入新的功能,但直接在类上修改不变的情况下可以使用Decorator 设计模式完成。通过传入需要增加功能的类,在decorator 类的方法中对原类进行操作,从而免去了继承的不变。
II. 例子
假设现在有一家甜品店开业,店中产品有donuts和ice cream;而在donuts 、ice cream上可以加入不同的调料。如果采用继承的方式来表示各种加调料的两样产品的话,店中调料每一次更新就需要修改多个类,同时针对同一种调料,两个产品需要两个类来描述。
但使用Decorator 很好地省去了这个麻烦:每一种材料只需要一个类来描述了。
abstract class Desert {
protected String description;
public String getDescription() {
return description;
}
public abstract double cost();
}
class Donuts extends Desert {
public Donuts() {
description = "donuts";
}
@override
public double cost() {
return 1.5;
}
}
class IceCream extends Desert {
public IceCream() {
description = "ice cream";
}
@override
public double cost() {
return 2.1;
}
}
// 添加酱料
abstract class Material extends Desert {
protected Desert desert;
public Material(Desert desert) {
this.desert = desert;
}
public abstract void addSauce(Sauce sauce);
public abstract String toString();
}
class DonutsWithSauce extends Material {
public DonusWithSauce(Desert desert) {
super(desert);
}
@override
public void addSauce(Sauce sauce) {
desert.getDescription() = desert.getDescription() + sauce.name();
desert.cost() += sauce.cost();
}
@override
public String toString() {
return desert.getDescription() + " " + desert.cost();
}
}
class IceCreamWithSauce extends Material {
public IceCreamWithSauce(Desert desert) {
super(desert);
}
@override
public void addSauce(Sauce sauce) {
desert.getDescription() = desert.getDescription() + " with "+sauce.name();
desert.cost() += sauce.cost();
}
@override
public String toString() {
return desert.getDescription() + " " + desert.cost();
}
}
abstract class Sauce {
protected String description;
public String getDescription() {
return description;
}
public abstract double cost();
}
public class Ketchup extends Sauce {
public Ketchup() {
description = "ketchup";
}
@override
public double cost() {
return 0.2;
}
}
class Client {
public static void main (String [] args) {
DonutsWithSauce dws = new DonutsWithSauce(new Donuts());
dws.addSauce(new Ketchup());
System.out.println(dos);
}
}