装饰器模式是一种结构型设计模式,它允许动态地为对象添加新的行为,同时不改变其结构。通过将对象包裹在一个装饰器中,可以在运行时为对象添加额外的功能。
在装饰器模式中,有四个主要角色:
抽象组件(Component):定义了被装饰对象的接口,是装饰器和被装饰对象的共同基类或接口。它声明了一组操作,这些操作可以在具体组件或其装饰器中实现。
具体组件(Concrete Component):实现了抽象组件接口,是被装饰的对象。
抽象装饰器(Decorator):也是抽象组件的子类或接口,持有一个指向抽象组件的引用。它的主要作用是为具体组件或其他装饰器提供一个公共的接口,并在其中维护一些额外的状态和行为。
具体装饰器(Concrete Decorator):实现了抽象装饰器接口,是具体的装饰器类。它在装饰器模式中扮演了具体的装饰角色,对组件进行具体的装饰或增强。
装饰器模式的关键思想是将对象包裹在装饰器中,这样可以在不修改原始对象的情况下,动态地为对象添加新的行为或功能。这种设计模式使得功能的添加和扩展更加灵活,可以组合不同的装饰器,以达到不同的功能组合。
示例:
假设我们有一个简单的咖啡店,其中有一种基本的咖啡(ConcreteComponent),我们可以为这种咖啡添加调料(具体装饰器)来制作各种口味的咖啡。
csharp
Copy code
// 抽象组件
public interface ICoffee
{
string GetDescription();
double GetCost();
}
// 具体组件
public class BasicCoffee : ICoffee
{
public string GetDescription()
{
return "Basic Coffee";
}
public double GetCost()
{
return 2.0;
}
}
// 抽象装饰器
public abstract class CoffeeDecorator : ICoffee
{
protected ICoffee coffee;
public CoffeeDecorator(ICoffee coffee)
{
this.coffee = coffee;
}
public virtual string GetDescription()
{
return coffee.GetDescription();
}
public virtual double GetCost()
{
return coffee.GetCost();
}
}
// 具体装饰器
public class MilkDecorator : CoffeeDecorator
{
public MilkDecorator(ICoffee coffee) : base(coffee)
{
}
public override string GetDescription()
{
return base.GetDescription() + ", Milk";
}
public override double GetCost()
{
return base.GetCost() + 0.5;
}
}
// 具体装饰器
public class SugarDecorator : CoffeeDecorator
{
public SugarDecorator(ICoffee coffee) : base(coffee)
{
}
public override string GetDescription()
{
return base.GetDescription() + ", Sugar";
}
public override double GetCost()
{
return base.GetCost() + 0.3;
}
}
在上述示例中,ICoffee是抽象组件接口,BasicCoffee是具体组件实现。CoffeeDecorator是抽象装饰器,MilkDecorator和SugarDecorator是具体装饰器,它们都继承自CoffeeDecorator。通过装饰器,我们可以动态地给咖啡添加不同的调料,而不需要修改咖啡的实现。例如,我们可以通过以下方式为咖啡添加调料:
csharp
Copy code
ICoffee basicCoffee = new BasicCoffee();
Console.WriteLine("Description: " + basicCoffee.GetDescription());
Console.WriteLine("Cost: $" + basicCoffee.GetCost());
ICoffee coffeeWithMilk = new MilkDecorator(basicCoffee);
Console.WriteLine("Description: " + coffeeWithMilk.GetDescription());
Console.WriteLine("Cost: $" + coffeeWithMilk.GetCost());
ICoffee coffeeWithMilkAndSugar = new SugarDecorator(coffeeWithMilk);
Console.WriteLine("Description: " + coffeeWithMilkAndSugar.GetDescription());
Console.WriteLine("Cost: $" + coffeeWithMilkAndSugar.GetCost());
输出结果:
Description: Basic Coffee
Cost: $2
Description: Basic Coffee, Milk
Cost: $2.5
Description: Basic Coffee, Milk, Sugar
Cost: $2.8
通过装饰器模式,我们可以方便地根据需求组合不同的装饰器,从而实现不同的咖啡口味,并且这些功能的扩展是灵活和可维护的。