C#设计模式实战:生成器与责任链模式的实现

雨后青山
雨后青山
发布时间:2026-10-16 | 3人浏览过
原创

本文深入解析C#中的两种常用设计模式:生成器模式与责任链模式。通过构建度假计划和邮件处理的实际案例,详细展示了如何利用生成器模式分步构造复杂对象以封装创建过程,以及如何通过责任链模式解耦请求发送者与接收者,实现链式处理逻辑。

生成器模式

生成器模式(Builder Pattern)的核心在于将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。其关键在于封装产品的构造步骤,允许按特定顺序逐步完成对象的初始化。

假设我们需要为一个旅行应用构建“度假计划”数据结构。每位游客的行程安排差异巨大,涉及天数、旅馆、景点、活动和餐饮等多个维度。如果采用传统构造函数一次性传入所有参数,不仅参数列表冗长,且难以处理可选属性或缺省值。因此,我们将旅游规划的创建过程封装在一个独立的“生成器”对象中,由客户按需调用不同方法来填充数据。

设计思路

我们采用抽象生成器定义构建步骤的接口,再由具体生成器实现这些步骤。这种设计将复杂的组装逻辑隐藏在内部,对外只暴露简洁的调用方式。

C# 代码实现

首先定义用于存储数据的 Vacation 类:

public class Vacation
{
    public int Day { get; set; }
    public string Hotel { get; set; }
    public string Park { get; set; }
    public string Activity { get; set; }
    public string Meal { get; set; }
}

接着定义抽象生成器 AbstractBuilder,规定必须实现的构建方法:

public abstract class AbstractBuilder
{
    public abstract void BuildDay(int day);
    public abstract void Hotel(string hotel);
    public abstract void Park(string park);
    public abstract void Activity(string activity);
    public abstract void Meal(string meal);
    public abstract Vacation GetVacationPlanner();
}

然后实现具体的生成器 VacationBuilder,负责将步骤应用于实际对象:

public class VacationBuilder : AbstractBuilder
{
    private Vacation vacation = new Vacation();

    public override void BuildDay(int day)
    {
        vacation.Day = day;
    }

    public override void Hotel(string hotel)
    {
        vacation.Hotel = hotel;
    }
    public override void Activity(string activity)
    {
        vacation.Activity = activity;
    }
    public override void Meal(string meal)
    {
        vacation.Meal = meal;
    }

    public override void Park(string park)
    {
        vacation.Park = park;
    }

    public override Vacation GetVacationPlanner()
    {
        return vacation;
    }
}

最后,客户端可以通过链式调用或直接调用来使用生成器:

var builder = new VacationBuilder();
builder.BuildDay(1);
builder.Hotel("Grand Hotel");
builder.Park("Disneyland");
// ... 其他步骤
Vacation plan = builder.GetVacationPlanner();

生成器模式的优点

  1. 封装复杂性:将复杂对象的创建过程和表示隔离,隐藏了内部的构建细节。
  2. 灵活的控制:允许客户通过改变构建过程的顺序或步骤来创建不同的产品。
  3. 隐藏内部表现:客户端无需了解产品内部结构的具体实现。
  4. 替换实现:只要遵循抽象接口,就可以轻松替换具体的生成器实现。

局限性与适用场景

  • 适用场景:常用于创建具有多个组成部分或需要按特定顺序构建的组合型对象。
  • 局限性:相比于工厂模式,客户端需要更深入了解领域知识才能正确指挥构建过程;若产品变化极小,则可能显得过于复杂。

责任链模式

责任链模式(Chain of Responsibility Pattern)旨在避免请求发送者与接收者之间的耦合。它使多个对象都有机会处理请求,将这些对象连成一条链,并沿着这条链传递请求,直到有一个对象处理它为止。

以一个公司邮件处理系统为例:接收到的邮件需要根据类型分发。个人邮件由收件人直接处理,工作邮件转发给经理,垃圾邮件则由系统自动删除。如果使用多重 if-else 判断,每当新增一种邮件类型时都需要修改核心代码。而责任链模式允许动态地增加或移除处理节点。

C# 代码实现

首先定义一个枚举来表示邮件类型,以及抽象的处理者基类:

/// <summary>
/// 邮件类型
/// </summary>
public enum EmailType
{
    Self = 1,
    Manager = 2,
    Del = 3
}

public abstract class Handler
{
    public Handler nextHandler;
    public EmailType type;

    public Handler(EmailType type) {
        this.type = type;
    }

    public void SetNextHandler(Handler nextHandler)
    {
        this.nextHandler = nextHandler;
    }

    public abstract void HandleRequest(EmailType requsetType);
}

接下来实现具体的处理者,例如处理个人邮件的 SelfHandler:

class SelfHandler : Handler
{
    public SelfHandler() : base(EmailType.Self) { }

    public override void HandleRequest(EmailType requsetType)
    {
        if (EmailType.Self == requsetType)
        {
            Console.WriteLine("邮件由自己处理");
        }
        else
        {
            if (nextHandler != null)
            {
                nextHandler.HandleRequest(requsetType);
            }
        }
    }
}

同理实现经理处理者 ManagerHandler 和垃圾邮件删除者 DelHandler:

class ManagerHandler : Handler
{
    public ManagerHandler() : base(EmailType.Manager) { }

    public override void HandleRequest(EmailType requsetType)
    {
        if (EmailType.Manager == requsetType)
        {
            Console.WriteLine("邮件转到经理处理");
        }
        else
        {
            if (nextHandler != null)
            {
                nextHandler.HandleRequest(requsetType);
            }
        }
    }
}

class DelHandler : Handler
{
    public DelHandler() : base(EmailType.Del) { }

    public override void HandleRequest(EmailType requsetType)
    {
        if (EmailType.Del == requsetType)
        {
            Console.WriteLine("垃圾邮件已删除");
        }
        else
        {
            if (nextHandler != null)
            {
                nextHandler.HandleRequest(requsetType);
            }
        }
    }
}

在客户端组装责任链并进行测试:

class Program
{
    static void Main(string[] args)
    {
        // 1. 组装责任链
        Handler selfHandler = new SelfHandler();
        Handler managerHandler = new ManagerHandler();
        Handler delHandler = new DelHandler();

        selfHandler.SetNextHandler(managerHandler);
        managerHandler.SetNextHandler(delHandler);

        // 2. 发起请求测试
        Console.WriteLine("--- 测试流程 ---");
        selfHandler.HandleRequest(EmailType.Del);   // 应该输出: 垃圾邮件已删除
        selfHandler.HandleRequest(EmailType.Manager); // 应该输出: 邮件转到经理处理
        selfHandler.HandleRequest(EmailType.Self);    // 应该输出: 邮件由自己处理

        Console.ReadKey();
    }
}

责任链模式的优点

  1. 解耦发送者与接收者:发送请求的对象只需将请求发给链首,无需关心谁最终处理。
  2. 简化对象:对象无需知道链的结构,只需关注自己的处理逻辑。
  3. 动态扩展:可以随时调整链的成员顺序,或动态新增/删除特定的责任节点。

局限性与适用场景

  • 适用场景:常用于窗口系统的事件处理(如鼠标、键盘事件)、权限验证流程、日志过滤等需要按顺序或条件流转的场景。
  • 局限性:不保证请求一定被处理(若链尾未处理则可能被丢弃);调试时不易追踪整个链条的执行状态;若链条过长可能影响性能。

总结

生成器模式侧重于构造处理,通过链式传递实现请求的分发与解耦。在实际的C#开发中,理解这两种模式的适用边界,能够帮助你写出更清晰、易维护的业务逻辑代码。以上就是C#设计模式中生成器模式和责任链模式的详细内容,更多关于C#进阶实践的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表