设计模式之 装饰器模式 C# 范例

装饰器模式(Decorator Pattern)是一种结构型设计模式,允许你动态地给一个对象添加额外的职责。装饰器模式通常用于在不改变对象本身的情况下,给对象增加新的行为。

关键点:

  • Component:定义一个接口,可以是抽象类或接口。
  • ConcreteComponent :实现了 Component 接口的具体类。
  • Decorator :继承自 Component,并持有一个 Component 实例,用于在此基础上增加额外的行为。
  • ConcreteDecorator :继承自 Decorator,并可以在装饰器中添加具体的功能。

示例代码

下面是一个简单的装饰器模式实现示例,模拟了为 Drink 类添加不同的"配料"来增强饮品的功能。

1. 定义 Drink 接口和实现类
复制代码
cs 复制代码
// 抽象基类
public interface IDrink
{
    double Cost();  // 计算饮品的价格
    string Description();  // 获取饮品描述
}

// 具体的饮品
public class Coffee : IDrink
{
    public double Cost() => 5.0;
    public string Description() => "Coffee";
}

public class Tea : IDrink
{
    public double Cost() => 3.0;
    public string Description() => "Tea";
}
2. 定义装饰器类
复制代码
cs 复制代码
// 装饰器基类,继承自 IDrink 并包含对 IDrink 的引用
public abstract class DrinkDecorator : IDrink
{
    protected IDrink _drink;

    public DrinkDecorator(IDrink drink)
    {
        _drink = drink;
    }

    public virtual double Cost() => _drink.Cost();  // 默认返回基础饮品的价格
    public virtual string Description() => _drink.Description();  // 默认返回基础饮品的描述
}
3. 创建具体的装饰器类
复制代码
cs 复制代码
// 添加牛奶的装饰器
public class MilkDecorator : DrinkDecorator
{
    public MilkDecorator(IDrink drink) : base(drink) { }

    public override double Cost() => _drink.Cost() + 1.5;  // 添加牛奶的价格
    public override string Description() => _drink.Description() + ", Milk";  // 添加描述
}

// 添加糖的装饰器
public class SugarDecorator : DrinkDecorator
{
    public SugarDecorator(IDrink drink) : base(drink) { }

    public override double Cost() => _drink.Cost() + 0.5;  // 添加糖的价格
    public override string Description() => _drink.Description() + ", Sugar";  // 添加描述
}
4. 使用装饰器
复制代码
cs 复制代码
class Program
{
    static void Main(string[] args)
    {
        // 创建基础饮品
        IDrink myCoffee = new Coffee();
        Console.WriteLine($"Description: {myCoffee.Description()}, Cost: {myCoffee.Cost()}");

        // 装饰饮品,添加牛奶
        myCoffee = new MilkDecorator(myCoffee);
        Console.WriteLine($"Description: {myCoffee.Description()}, Cost: {myCoffee.Cost()}");

        // 再装饰,添加糖
        myCoffee = new SugarDecorator(myCoffee);
        Console.WriteLine($"Description: {myCoffee.Description()}, Cost: {myCoffee.Cost()}");

        // 输出:添加了牛奶和糖后的最终饮品
        Console.WriteLine($"Final Description: {myCoffee.Description()}, Final Cost: {myCoffee.Cost()}");
    }
}

输出结果:

复制代码
cs 复制代码
Description: Coffee, Cost: 5
Description: Coffee, Milk, Cost: 6.5
Description: Coffee, Milk, Sugar, Cost: 7
Final Description: Coffee, Milk, Sugar, Final Cost: 7

解释:

  1. 基础饮品 :我们首先创建了一个 Coffee 对象,其基础价格为 5.
  2. 装饰器 :然后通过 MilkDecoratorSugarDecorator 为这个饮品添加了额外的配料(牛奶和糖)。
  3. 最终结果:最终,我们得到了一个描述为"Coffee, Milk, Sugar"的饮品,并且总价格是 7.

通过装饰器模式,我们可以动态地添加或删除行为,而不需要修改原有的类结构。这个模式非常适用于需要在运行时根据需要扩展对象行为的场景。

相关推荐
z落落18 分钟前
C# WinForm 线程池与事件等待+进度条暂停恢复实战案例
开发语言·c#
workflower1 小时前
人形机器人全身运动控制能力大幅提升
人工智能·深度学习·机器学习·设计模式·机器人·自动化
折哥的程序人生 · 物流技术专研1 小时前
Java 23 种设计模式:从踩坑到精通 | 备忘录模式 —— 快照与撤销,给对象装一个“后悔药”
java·设计模式·备忘录模式·行为型模式·java设计模式·从踩坑到精通·撤销重做
Kel1 小时前
万物皆 Runnable:LangChain 如何用一个接口统一模型、链与图
人工智能·设计模式·架构
酷酷的身影2 小时前
Managers/APConfigManager.cs
开发语言·ui·c#
ttod_qzstudio4 小时前
【软考设计模式】策略模式:算法族的封装与动态切换精讲
设计模式·策略模式
咖啡八杯12 小时前
GoF设计模式——迭代器模式
java·后端·设计模式·迭代器模式
ttod_qzstudio14 小时前
【软考设计模式】外观模式:复杂子系统的“门面“封装与代码填空精讲
设计模式·外观模式
贾斯汀frank14 小时前
C# 15 类型系统改进:Union Types
开发语言·windows·c#
时代的狂16 小时前
如何理解 C# 的 async 和 await
c#·.netcore·async·await