mcpField
G
gof-builder

gof-builder

github.com/yonatankarp开发143 次安装23 周前更新
代码仓库

关于 gof-builder

介绍 GoF Builder 模式的技能,面向需要组装复杂对象的开发者。内容涵盖流式构建器和类型安全 DSL,并说明何时应优先使用命名参数或默认值。

主要功能

  1. 01通过分步构造组装对象
  2. 02支持流式构建器形式
  3. 03介绍类型安全 DSL 构建器
  4. 04说明 Builder 与 Factory 的区别
  5. 05强调构建时验证对象

适用场景

  1. 01构造函数包含许多可选参数
  2. 02对象需按多个步骤完成组装
  3. 03希望调用代码呈现清晰的组装流程

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/yonatankarp/software-design-skills --skill gof-builder

安装后在 Claude Code 中输入/gof-builder确认已加载。

详细介绍

一句话总结

将复杂对象的构造与其表示分离,让同一构造流程能够生成不同结果,并用流畅、易读的组装方式取代“伸缩构造函数”。

何时使用此技能

  • 对象有很多构造函数参数(约 4 个以上),其中有几个是可选的。
  • 构造过程分多个步骤进行(制作汉堡,然后添加配料,再包装),且步骤可能有所不同。
  • 你希望调用代码读起来像菜谱,而不是费力应对构造函数签名。
  • Kotlin DSL 惯用写法——html { head { … } body { … } }——就是一种构建器。

何时不使用此技能

  • 构造函数只接受 1–3 个参数,直接调用清晰易读。
  • 该语言已经提供了更好的工具——Kotlin 的命名参数 + 默认参数值在大多数情况下无需 Builder。只有当构造确实需要分阶段进行时(需要中间验证或类型安全的步骤顺序),才使用 Builder。
  • 你要构建的是单个不可变值对象——使用带命名参数的 data class 几乎总是足够的。

何时选择 Builder 而不是 Factory(gof-factory)

  • Factory 隐藏了要实例化哪种具体类型。
  • Builder 隐藏了如何组装一个类型已知的实例。

二者可以组合使用:Factory 可以返回 Builder;Builder 也可以使用 Factory 构建子部件。

核心内容

两种常见形式:

流式构建器。 Builder 类通过链式 setter 方法累积状态,并以 build() 结束:

Burger.builder()
  .bun(Brioche)
  .patty(Beef)
  .topping(Cheese).topping(Bacon)
  .build()

每个 setter 都返回 this(或 Builder),以便链式调用。build() 会进行验证并返回完成后的对象。目标类型应使用私有构造函数,以确保调用方必须通过构建器创建对象。

类型安全的 DSL 构建器(Kotlin 惯用写法,但这个概念更早就已存在)。函数接受一个带接收者的 lambda;在 lambda 内部,可以直接使用构建器的方法。Kotlin 标准库中的 buildString { append("hello"); append(" world") } 是最简单的例子。HTML 风格的构建器则更进一步。

一个常见错误是为实际上并不需要 Builder 的对象实现 Builder——只有当构造复杂到单次构造函数调用会掩盖意图时,Builder 才有意义。

决策启发

  • 统计构造函数参数的数量。少于约 4 个时,Builder 属于过度设计——使用命名参数。
  • 查看是否有带合理默认值的可选参数。如果大多数参数都有默认值,命名参数 + 默认值比 Builder 更易读。
  • 如果构造需要多个阶段,且第 N 阶段依赖第 N−1 阶段,那么 Builder(尤其是基于类型状态的 Builder)就值得采用。
  • 如果目标对象应当不可变,build() 必须生成经过完整验证的值,并且构建器本身应被丢弃。

反模式

  • 明明使用命名参数就够了,却使用 Builder——徒增形式,没有收益。
  • 允许 build() 返回无效对象的构建器——这违背了安全性目的。
  • “Builder”类持有对已构建对象的可变引用,并在 build() 之后继续修改它。
  • 在多个线程之间共享同一个 Builder 实例——Builder 通常有状态,并不安全。

另请参阅

  • gof-factory — Builder 隐藏组装过程;Factory 隐藏类型选择。二者可以组合使用。
  • gof-prototype — 当现有实例是更便捷的起点时,可将其作为 Builder 的替代方案。
  • gof-kotlin-idioms — 命名参数 + 默认值在大多数 Kotlin 代码中可以取代 Builder;类型安全的 Builder DSL 是主要例外。

参考资料

  • Design Patterns(GoF,1994),第 3 章——Builder。(未收录于《HFDP》第 2 版;该书仅略有涉及。)
  • Kotlin Design Patterns and Best Practices(Alexey Soshin),第 2 章——Builder,并明确与 Kotlin 的命名参数进行比较。

评论

支持 Markdown