使用装饰者设计模式,可以动态对已有对象附加新功能,在对象功能扩展方面,它比继承更有弹性。
如喝咖啡,选择咖啡类型后可以再选择一种或多种配料,而如果加入新的咖啡类型、新的配料可以不修改原有代码。
以下C#控制台代码:
using System;
namespace ConsoleApp1
{
// 被装饰对象的基类
public abstract class Drink
{
private float price = 0f;
private string description = "";
public void setDescription(string description)
{
this.description = description;
}
public string getDescription()
{
return description;
}
public void setPrice(float price)
{
this.price = price;
}
public float getPrice()
{
return price;
}
public abstract float cost();
}
// 咖啡 被装饰对象
public class Coffee : Drink
{
public override float cost()
{
return this.getPrice();
}
}
// 咖啡 具体被装饰对象
public class ShortBlack : Coffee
{
public ShortBlack()
{
this.setDescription("ShortBlack");
this.setPrice(16.0f);
}
}
// 扩展新的 Coffee
// 配料 装饰者
public class Decorator : Drink
{
private Drink Obj;
public Decorator(Drink Obj)
{
this.Obj = Obj;
}
public override float cost()
{
return this.getPrice() + Obj.cost();
}
}
// 配料 具体装饰者
public class Milk : Decorator
{
public Milk(Drink Obj) : base(Obj)
{
this.setDescription("Milk");
this.setPrice(2.0f);
}
}
public class Chocolate : Decorator
{
public Chocolate(Drink Obj) : base(Obj)
{
this.setDescription("Chocolate");
this.setPrice(5.0f);
}
}
// 扩展新的 Decorator
class Program
{
static void Main(string[] args)
{
Drink drink = new ShortBlack();
Console.WriteLine("咖啡:{0}-价格:{1}-总价:{2}", drink.getDescription(), drink.getPrice(), drink.cost());
drink = new Milk(drink);
Console.WriteLine("配料:{0}-价格:{1}-总价:{2}", drink.getDescription(), drink.getPrice(), drink.cost());
drink = new Chocolate(drink);
Console.WriteLine("配料:{0}-价格:{1}-总价:{2}", drink.getDescription(), drink.getPrice(), drink.cost());
}
}
}