装饰模式:给爱用继承的人一个全新的设计眼界
以咖啡菜单作为实例:
namespace 设计模式.装饰模式
{
//饮料的基类
public abstract class Beverage
{
public String description = "Unkown Beverage";
public String getDescription()
{
return description;
}
public abstract double cost();
}
//装饰基类为浓缩咖啡
public class Espresso : Beverage
{
public Espresso()
{
base.description = "浓缩咖啡";
}
public override double cost()
{
return 1.99;
}
}
//装饰基类为HouseBlend咖啡
public class HouseBlend : Beverage { public HouseBlend() { base.description = "House Blend Coffee"; } public override double cost() { return 0.89; } }
//装饰基类为DarkRoast咖啡
public class DarkRoast : Beverage { public DarkRoast() { base.description = "Dark Roast Coffee"; } public override double cost() { return 1.11; } }
//装饰基类为Decatt咖啡
public class Decat : Beverage
{
public Decat()
{
base.description = "Decat Coffee";
}
public override double cost()
{
return 2.22;
}
}
//装饰基类为调味料抽象基类
public abstract class CondimentDecorator : Beverage { public abstract String getDescription(); }
//装饰调味料抽象基类为“摩卡+基类的子类”咖啡
public class Mocha : CondimentDecorator { Beverage beverage;
//构造是传入饮料类或其子类
public Mocha(Beverage beverage)
{
this.beverage = beverage;
}
//描述=饮料描述+调味料描述
public override String getDescription()
{
return beverage.getDescription() + ", Mocha";
}
//总价格=调味料"摩卡"+传入饮料"beverage"的价格
public override double cost() {
return 0.2 + beverage.cost();
}
}
//解释同上
public class Soy : CondimentDecorator
{
Beverage beverage;
public Soy(Beverage beverage)
{
this.beverage = beverage;
}
public override String getDescription()
{
return beverage.getDescription() + ", Soy";
}
public override double cost()
{
return 0.30 + beverage.cost();
}
}
//解释同上
public class Whip : CondimentDecorator { Beverage beverage; public Whip(Beverage beverage) { this.beverage = beverage; } public override String getDescription() { return beverage.getDescription() + ", Whip"; } public override double cost() { return 0.40 + beverage.cost(); } }}
总结:
1.一旦你熟悉了装饰的技巧,你将能够在不修改任何底层代码的情况下,给你的(或别人的)对象赋予新的职责(前提是那个的底层代码真的很棒,没啥BUG)。2.本设计模式符合了“开放-关闭原则”:类应该对扩展开放,对修改关闭。
3.动态的将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。