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关键字有什么作用

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

相关推荐
烤麻辣烫4 小时前
23种设计模式(新手)-3接口隔离原则
java·开发语言·学习·设计模式·intellij-idea
e***U8205 小时前
算法设计模式
算法·设计模式
颜酱6 小时前
理解编程的设计模式(前端角度)
设计模式
ZHE|张恒7 小时前
设计模式(五)原型模式 — 通过克隆快速复制对象,避免复杂初始化
设计模式·原型模式
敖云岚21 小时前
【设计模式】简单易懂的行为型设计模式-策略模式
设计模式·策略模式
IT永勇1 天前
C++设计模式-单例
c++·单例模式·设计模式
ZHE|张恒1 天前
设计模式(四)建造者模式 — 分步骤构建复杂对象,让创建过程可控可扩展
设计模式·建造者模式
ZHE|张恒1 天前
设计模式(三)抽象工厂模式 — 一次性创建一整套相关对象的终极工厂
设计模式·抽象工厂模式
崎岖Qiu1 天前
状态模式与策略模式的快速区分与应用
笔记·设计模式·状态模式·策略模式·开闭原则