当前位置:首页 > 技术 > 正文内容

深入理解建造者模式及其在 .NET 中的实现

访客 技术 2026年5月31日 1

建造者模式(Builder Pattern)是一种创建型设计模式,其核心思想是将一个复杂对象的构建过程与其表示分离。通过这种方式,同样的构建逻辑可以产生不同的对象配置。该模式特别适用于那些构造过程复杂、且需要通过多个步骤逐步完成的对象创建场景。

核心原理

在建造者模式中,客户端不需要了解对象内部的精细组成部分以及具体的装配细节,只需指定所需的建造者类型。这种解耦机制使得系统在引入新的建造逻辑时具有极高的扩展性。具体而言,它将对象的"如何构建"与"由什么组成"进行了明确的职责划分。

以下是一个展示抽象构建流程的基础示例,演示了如何通过抽象基类定义固定的步骤序列:


// 定义抽象流程执行器
public abstract class TaskFlow
{
    protected abstract void PrepareEnvironment();
    protected abstract void ExecuteCoreLogic();
    protected abstract void CleanupResources();

    // 模板方法,控制执行顺序
    public void Run()
    {
        PrepareEnvironment();
        ExecuteCoreLogic();
        CleanupResources();
    }
}

// 具体业务实现
public class DataMigrationTask : TaskFlow
{
    protected override void PrepareEnvironment()
    {
        Console.WriteLine("连接数据库并备份元数据...");
    }

    protected override void ExecuteCoreLogic()
    {
        Console.WriteLine("执行数据迁移与校验逻辑...");
    }

    protected override void CleanupResources()
    {
        Console.WriteLine("释放连接并发送执行报告...");
    }
}

// 调用示例
// var task = new DataMigrationTask();
// task.Run();

复杂对象的组装与依赖注入实践

在实际的工程开发中,建造者模式常用于配置复杂的实体模型。例如,在游戏开发或系统配置中,一个对象可能包含多个属性(如硬件配置、外观参数等),且这些属性在不同场景下有不同的组合方式。结合现代 .NET 的依赖注入(DI)容器,我们可以更加优雅地管理这些建造者的生命周期。

以下代码展示了如何利用 Microsoft.Extensions.DependencyInjection 实现一个灵活的电脑配置构建系统:


using Microsoft.Extensions.DependencyInjection;

// 产品类:复杂的电脑配置
public class ComputerConfig
{
    public string CPU { get; set; } = string.Empty;
    public string GPU { get; set; } = string.Empty;
    public string Memory { get; set; } = string.Empty;
    public string Storage { get; set; } = string.Empty;
    public string CaseType { get; set; } = string.Empty;
}

// 抽象建造者
public abstract class ComputerBuilder
{
    protected readonly ComputerConfig _config;
    
    protected ComputerBuilder(ComputerConfig config)
    {
        _config = config;
    }

    public abstract void SetProcessor();
    public abstract void SetGraphics();
    public abstract void SetMemorySize();
    public abstract void SetStorageDisk();
    public abstract void SetChassis();

    public ComputerConfig GetResult() => _config;
}

// 具体建造者:工作站配置
public class WorkstationBuilder : ComputerBuilder
{
    public WorkstationBuilder(ComputerConfig config) : base(config) { }

    public override void SetProcessor() => _config.CPU = "Threadripper 5995WX";
    public override void SetGraphics() => _config.GPU = "RTX A6000";
    public override void SetMemorySize() => _config.Memory = "256GB ECC DDR4";
    public override void SetStorageDisk() => _config.Storage = "4TB NVMe SSD";
    public override void SetChassis() => _config.CaseType = "Full Tower";
}

// 具体建造者:办公电脑配置
public class OfficePCBuilder : ComputerBuilder
{
    public OfficePCBuilder(ComputerConfig config) : base(config) { }

    public override void SetProcessor() => _config.CPU = "Core i5-12400";
    public override void SetGraphics() => _config.GPU = "Integrated Graphics";
    public override void SetMemorySize() => _config.Memory = "16GB DDR4";
    public override void SetStorageDisk() => _config.Storage = "512GB SATA SSD";
    public override void SetChassis() => _config.CaseType = "Mini ITX";
}

// 指挥者:负责构建顺序
public class AssemblyDirector
{
    private readonly ComputerBuilder _builder;

    public AssemblyDirector(ComputerBuilder builder)
    {
        _builder = builder;
    }

    public ComputerConfig Construct()
    {
        _builder.SetProcessor();
        _builder.SetGraphics();
        _builder.SetMemorySize();
        _builder.SetStorageDisk();
        _builder.SetChassis();
        return _builder.GetResult();
    }
}

// 客户端调用与 DI 注册
var services = new ServiceCollection();

// 注册具体建造者和指挥者
services.AddTransient<ComputerBuilder, WorkstationBuilder>();
services.AddTransient<AssemblyDirector>();
services.AddTransient<ComputerConfig>();

var serviceProvider = services.BuildServiceProvider();

// 从容器中获取指挥者并执行构建
var director = serviceProvider.GetRequiredService<AssemblyDirector>();
var myPC = director.Construct();

Console.WriteLine("--- 电脑配置单 ---");
Console.WriteLine($"处理器: {myPC.CPU}");
Console.WriteLine($"显卡:   {myPC.GPU}");
Console.WriteLine($"内存:   {myPC.Memory}");
Console.WriteLine($"硬盘:   {myPC.Storage}");
Console.WriteLine($"机箱:   {myPC.CaseType}");

应用总结

建造者模式通过将构建逻辑封装在具体的 Builder 类中,不仅简化了 Director 的逻辑,还允许我们在不修改现有代码的情况下,通过增加新的 Builder 子类来扩展系统功能。在涉及 DI 容器时,这种模式能有效地解决复杂对象生命周期管理和依赖注入的冲突,使系统架构更加健壮且易于测试。

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。