C#42、什么是建造者设计模式

建造者设计模式(Builder Design Pattern) 是一种 创建型设计模式,它的核心目标是:

将一个复杂对象的构建过程与其表示分离,使得同样的构建过程可以创建不同的表示。

简单说:当你需要创建一个有很多可选参数或步骤的对象时,用建造者模式可以让代码更清晰、安全、易读。


🧱 为什么需要建造者模式?

❌ 问题:传统方式创建复杂对象很痛苦

假设你要创建一个 Product 对象,它有 10 个属性,其中 5 个是可选的:

方式1:多构造函数("重叠构造函数"反模式)
复制代码
public Product(string name) { ... }
public Product(string name, string color) { ... }
public Product(string name, string color, int size) { ... }
// ... 组合爆炸!难以维护
方式2:setter 方法(但对象可能处于不一致状态)
复制代码
var product = new Product();
product.Name = "Laptop";
product.Color = "Silver";
// 忘记设置 Price?对象不完整!
方式3:巨型构造函数(参数太多,易错)
复制代码
new Product("Laptop", "Silver", null, 15, true, false, "Intel", ...); // 谁看得懂?

✅ 建造者模式如何解决?

它引入一个 "建造者(Builder)" 类,提供 链式调用(Fluent Interface) 的方式逐步设置属性,最后调用 Build() 创建最终对象。

🔧 核心角色:

角色 说明
Product(产品) 要创建的复杂对象
Builder(抽象建造者) 定义创建各部分的接口(C# 中常用接口或抽象类)
ConcreteBuilder(具体建造者) 实现 Builder,负责组装 Product
Director(指挥者,可选) 封装固定的构建流程(非必须)

✅ C# 示例:建造一台电脑

1️⃣ 产品类(不可变推荐)

复制代码
public class Computer
{
    public string CPU { get; }
    public string RAM { get; }
    public string Storage { get; }
    public bool HasGPU { get; }

    // 私有构造函数,只能通过 Builder 创建
    private Computer(ComputerBuilder builder)
    {
        CPU = builder.CPU;
        RAM = builder.RAM;
        Storage = builder.Storage;
        HasGPU = builder.HasGPU;
    }

    // 嵌套 Builder 类(常见做法)
    public class Builder
    {
        public string CPU { get; private set; }
        public string RAM { get; private set; }
        public string Storage { get; private set; }
        public bool HasGPU { get; private set; }

        public Builder SetCPU(string cpu)
        {
            CPU = cpu;
            return this; // 支持链式调用
        }

        public Builder SetRAM(string ram)
        {
            RAM = ram;
            return this;
        }

        public Builder SetStorage(string storage)
        {
            Storage = storage;
            return this;
        }

        public Builder WithGPU(bool hasGpu = true)
        {
            HasGPU = hasGpu;
            return this;
        }

        public Computer Build()
        {
            // 可在此添加验证逻辑
            if (string.IsNullOrEmpty(CPU))
                throw new InvalidOperationException("CPU is required");

            return new Computer(this);
        }
    }
}

2️⃣ 使用建造者(清爽!)

复制代码
var gamingPC = new Computer.Builder()
    .SetCPU("Intel i9")
    .SetRAM("32GB DDR5")
    .SetStorage("2TB NVMe SSD")
    .WithGPU(true)
    .Build();

var officePC = new Computer.Builder()
    .SetCPU("Intel i5")
    .SetRAM("16GB DDR4")
    .SetStorage("512GB SSD")
    // 不调用 WithGPU,默认 false
    .Build();

优点

  • 代码可读性强(像自然语言)
  • 参数顺序无关
  • 可选参数灵活
  • 最终对象可以是不可变的(线程安全)
  • 构建过程可加验证

🆚 建造者 vs 其他模式

模式 适用场景
建造者(Builder) 对象有多个可选组成部分,构建过程复杂
工厂(Factory) 根据条件创建不同子类实例 (如 CreateCar("BMW")
原型(Prototype) 通过复制现有对象来创建新对象

💡 建造者关注"怎么一步步构建一个复杂对象 ",工厂关注"该返回哪个具体类型"。


✅ 真实应用场景

  1. StringBuilder(名字就体现了!)

    复制代码
    var sb = new StringBuilder();
    sb.Append("Hello").Append(" ").Append("World");
    string result = sb.ToString(); // Build!
  2. ASP.NET Core 配置

    复制代码
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddControllers();
    builder.Configuration.AddJsonFile("appsettings.json");
    var app = builder.Build(); // 最终构建 WebApplication
  3. HTTP 客户端构建

    复制代码
    var client = new HttpClientBuilder()
        .WithBaseAddress("https://api.example.com")
        .WithTimeout(TimeSpan.FromSeconds(30))
        .WithRetryPolicy(3)
        .Build();
  4. SQL 查询构建器

    复制代码
    var query = SqlBuilder.Select("Id, Name")
                         .From("Users")
                         .Where("Age > @age")
                         .OrderBy("Name")
                         .Build();

⚠️ 注意事项

  • 不要过度使用:如果对象只有 2~3 个参数,直接用构造函数更简单。
  • Builder 类通常作为 Product 的嵌套类(如上面示例),保持封装性。
  • 最终对象建议设计为不可变(只读属性),提高安全性。

✅ 小结

关键点 说明
目的 分离复杂对象的构建与表示
核心 用 Builder 逐步设置属性,最后 Build()
优势 链式调用、可读性强、支持可选参数、对象可不可变
适用 对象有很多可选配置项(如配置、文档、UI 组件等

问题

使用建造者设计模式的好处是什么?

它允许逐步构建对象,有助于将复杂的构建逻辑封装在单独的类中。

缺点是什么

他需要大量额外的代码,许多构建的类的代码

with关键字有什么作用

它用于创建具有某些特定字段或字段设置为新值的记录副本

相关推荐
七月丶19 小时前
别再手动凑 PR 了:这个 AI Skill 会按仓库习惯自动建分支、拆提交、提 PR
人工智能·设计模式·程序员
刀法如飞19 小时前
从程序员到架构师:6大编程范式全解析与实践对比
设计模式·系统架构·编程范式
九狼20 小时前
Flutter + Riverpod +MVI 架构下的现代状态管理
设计模式
静水流深_沧海一粟2 天前
04 | 别再写几十个参数的构造函数了——建造者模式
设计模式
StarkCoder2 天前
从UIKit到SwiftUI的迁移感悟:数据驱动的革命
设计模式
阿星AI工作室2 天前
给openclaw龙虾造了间像素办公室!实时看它写代码、摸鱼、修bug、写日报,太可爱了吧!
前端·人工智能·设计模式
_哆啦A梦3 天前
Vibe Coding 全栈专业名词清单|设计模式·基础篇(创建型+结构型核心名词)
前端·设计模式·vibecoding
阿闽ooo6 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4966 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃6 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式