Communitygithub.com

Statusnone420/agent-skills

设计深层模块:小接口、真实接缝和接口级测试。适用于塑造模块 API、重构代码或选择测试接缝时。不适用于快速修补。

agent-skills 是什么?

本技能专注于代码库设计,核心是构建“深层模块”(deep modules):通过小巧的接口暴露大量行为,并将接口置于调用者和测试共同的接缝(seam)处。它旨在为调用者提供杠杆效应(leverage),为维护者提供局部性(locality),并让测试能够抵御重构。技能提供了明确的规则和精确的术语表,例如“模块”(module)、“接口”(interface)、“实现”(implementation)、“深度”(depth)、“接缝”(seam)和“适配器”(adapter)。它指导开发者进行删除测试、缩小接口、接受依赖而非创建依赖,以及优先返回结果而非产生副作用。该技能支持任何具备接口和实现的代码单元(函数、类、包、跨层切片),并建议在项目有 CONTEXT.md 术语表时结合使用领域术语。它并非快速修补工具,而是用于在模块 API 塑造、代码重构或测试接缝选择时做出架构决策。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Statusnone420/agent-skills/tree/HEAD/adapters/claude/plugins/agent-skills/skills/codebase-design

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

代码库设计

设计深层模块:将大量行为置于小而简洁的接口背后,并将该接口放在调用者和测试都能触及的接缝处。目标是为调用者提供杠杆效应,为维护者提供局部性,并让测试能够抵御重构。

规则

  • 深度是接口的属性,不是实现的属性。 一个深层模块可以由多个可互换的小部件构成;但它们不属于其接口的一部分。模块内部可以为自身测试保留接缝,同时也拥有接口处的外部接缝。
  • 执行删除测试。 想象删除这个模块。如果复杂性随之消失,它只是一个透传层。如果复杂性在调用者之间重新出现,那么它就有存在的价值。
  • 接口就是测试表面。 调用者和测试跨越的是同一个接缝。如果你需要绕过接口进行测试,模块的形状很可能不对。
  • 一个适配器意味着假设的接缝;两个才让它成为现实。 仅在确实存在差异的地方(通常是生产环境和测试环境)添加接缝。
  • 缩小接口。 更少的方法、更简单的参数、隐藏更多内部复杂性。
  • 接受依赖而非创建依赖。 将支付网关作为参数传入,而不是在函数内部构造它。
  • 优先返回结果而非产生副作用,只要设计允许这样做。

词汇表

请精确使用以下术语。不要替换为“组件”、“服务”、“API”或“边界”。

  • 模块: 任何具有接口和实现的东西,无论规模大小:一个函数、类、包或跨层切片。
  • 接口: 调用者正确使用模块所需知道的一切:类型、不变条件、顺序、错误模式、必需的配置和性能。不仅仅是签名。
  • 实现: 模块内部的代码。一个小适配器可以有很大的实现(例如 Postgres 仓库),而一个大适配器可以有很小的实现(例如内存模拟)。
  • 深度: 接口处的杠杆效应,即调用者或测试每学习一个接口单元所能获得的行为。当大量行为位于小巧的接口背后时,模块是深的;当接口的复杂度几乎与实现相当,模块就是浅的。
  • 接缝(Michael Feathers):一个无需编辑该位置即可改变行为的位置;即模块接口所在之处。选择接缝本身就是一项决策。
  • 适配器: 在接缝处填充接口的具体东西。它命名的是一个角色,而不是内容。
  • 杠杆效应: 调用者从深度中获得的收益。一个实现能回报多个调用点和测试。
  • 局部性: 维护者从深度中获得的收益。变更、缺陷、知识和验证都集中在一个地方。

已拒绝的表述:深度是实现行数与接口行数的比率,因为它鼓励填充;将“接口”仅理解为一个类型关键字或公共方法,因为太狭隘了;“边界”,因为它与 DDD 的限界上下文冲突。

如果项目维护了 CONTEXT.md 术语表,请在此术语的基础上同时使用其中的领域术语。

深入探讨

  • 要按依赖类型加深一组浅层模块,请阅读 DEEPENING.md。
  • 要比较几种截然不同的接口方案,请阅读 DESIGN-IT-TWICE.md。它可能会启动三个或更多子代理,因此只在用户明确要求时才使用。

相关技能