☰
把架构决策固化为可测试的代码:architecture-decision-record 中的 Fitness Functions 实战指南
2026/10/12 1:43:50 网站建设 项目流程

【免费下载链接】architecture-decision-record

Architecture decision record (ADR) examples for software planning, IT leadership, and template documentation

项目地址:https://gitcode.com/gh_mirrors/ar/architecture-decision-record
点击查看免费下载

本指南围绕 fitness-functions-for-decisions-as-code 文档 展开,讲解如何用编程代码编写客观的自动化检查(fitness function),持续验证架构决策是否被团队真正遵守,并介绍其与 ADR(架构决策记录)、持续集成、架构单元测试及 AI/LLM 的结合方式。读完本文,你将掌握 fitness function 的定义、落地路径、工具选型(ArchUnit / ArchUnitTS)以及可直接复用的 LLM 提示词模板。

什么是 Fitness Functions

Fitness functions(适应度函数)是用编程代码编写的、客观的自动化检查,用于验证决策是否正在被维护(maintained)。在 architecture-decision-record 仓库的定义中,fitness functions 让决策变得可测试(testable)和可保证(assurable):

  • Fitness functions 使决策可测试、可保证;
  • 用于决策的 fitness functions 能极大地帮助质量保证(quality assurance)、监管流程(regulatory processes)和治理目标(governance goals)。

其核心思想是:不要只把架构决策写进文档就结束,而是把决策"翻译"成一段可以自动运行、能明确给出通过(pass)或失败(fail)结果的代码检查。这样,决策就从"文字约定"升级为"程序约束"。

该内容在仓库的多语言索引页中作为"ADR 的下一步进阶概念"(Next step concepts for ADRs)的一部分被收录,位于架构图、视图与视角等进阶主题之后,是 ADR 实践走向工程化、自动化的重要一环。

决策记录与 Fitness Function 如何衔接

仓库文档给出了一个非常清晰的职责划分:

决策记录(decision record)记录决策,而 fitness function保证决策。

两者是一体两面的关系:ADR 回答"我们决定怎么做、为什么这么做",fitness function 回答"这个决定是否仍然在被遵守"。

文档中的对照示例:

  • 决策示例:我们出于审计需求使用事件溯源(event sourcing)。
  • Fitness function 示例:我们使用持续集成服务器测试,验证所有状态变更都必须产生事件(events)。

也就是说,当团队决定"用事件溯源满足审计需求"后,紧接着就应该写出一条自动化规则:任何状态变更如果不产生对应事件,构建就失败。这条规则就是该决策的 fitness function。

仓库中 choosing-a-database-technology 示例 也印证了这一思路:决策上下文里明确提到"事件数据库适合需要审计、事件溯源和复杂数据处理的应用程序"——当这类决策被接受后,就可以用 fitness function 来持续校验"系统是否真的以事件形式记录每次数据变更"。

为什么 Fitness Functions 有助于决策

文档总结了四个核心价值点,它们共同构成采用 fitness function 的理由:

  1. 客观度量(Objective measurements):Fitness functions 的结果只有通过或失败,工作成果可见、清晰,避免"我们觉得应该没问题"式的主观判断。
  2. 持续使用(Continuous use):Fitness functions 是你的"活规则"(living rules),在每次提交(commit)和每次构建(build)时运行,决策约束不会随时间流失而失效。
  3. 重构信心(Confidence to refactor):Fitness functions 会自动捕获决策规则错误。当代码演进、重构时,一旦违反既定决策,检查会立刻报警,而不是等代码评审或事故来发现。
  4. 可扩展治理(Scalable governance):Fitness functions 用自动化方式保证标准得到遵守,无需人工审查作为瓶颈,治理能力可以随团队和代码规模平滑扩展。

这四点中,"持续使用"与"可扩展治理"正是 fitness function 与 持续集成示例(continuous integration) 中所述价值(自动构建、测试、尽早发现错误、提升交付质量)相互呼应的关键:fitness function 本质上是把架构决策注入到 CI 管道中的自动化测试资产。

如何落地:让 Fitness Functions 成为 CI 的一等公民

在实践层面,fitness function 最常见的落地方式就是挂在持续集成(CI)服务器上,与普通单元测试、集成测试并列运行。以文档中的事件溯源决策为例,一个典型的落地流程是:

  1. 写决策:按仓库推荐的 ADR 编写方式 记录"使用事件溯源以满足审计需求"这一决策。
  2. 写检查:用项目语言编写断言——"每次状态变更必须产生对应事件",例如在事件写入接口的单元测试中强制校验。
  3. 挂 CI:将该检查注册到 CI 管道(如 GitHub Actions、Jenkins、GitLab CI 等),配置为每次提交和每次构建必跑。
  4. 失败即阻断:任何代码改动若绕过事件写入、或删除事件字段,CI 立即红牌,阻止合并。

从仓库源码结构看,持续集成示例 的 Consequences 部分也明确指出,自动化带来的正收益包括"提升软件质量与交付、时间与成本节约",而 fitness function 正是把"架构质量"纳入自动化测试范围的手段——它让架构约束不再依赖人工记忆,而是像普通测试一样成为工程流程的一部分。

架构单元测试:Java 用 ArchUnit,TypeScript/JavaScript 用 ArchUnitTS

除了在业务层写断言,另一种更贴近架构本身的落地方式是架构单元测试(architecture unit testing):直接针对代码的包结构、依赖关系、分层规则编写测试。文档推荐了两个工具:

  • ArchUnit:用于检查Java代码的架构规则,可使用任何普通的 Java 单元测试框架(如 JUnit)来运行。它可以直接断言"某些包不得依赖另一些包""类只能在特定层出现""禁止循环依赖"等规则,非常适合把 ADR 中的架构约束(如分层边界、模块隔离)转成可执行代码。
  • ArchUnitTS:用于检查TypeScript和JavaScript代码的架构规则,可通过 Jest、Vitest、Jasmine 等常用测试框架运行,为前端与 Node.js 项目提供同样的架构断言能力。

使用方式上,二者都遵循"规则即测试"的模式:把决策写成规则(rule),规则写进测试文件,由测试框架执行。这样,ADR 中"我们决定采用分层架构""禁止业务层直接依赖基础设施层"等表述,就变成了每次测试运行都会验证的硬性约束,与上一节"挂在 CI 上"的做法天然衔接。

需要说明的是,这类工具各有适用生态:ArchUnit 面向 JVM 生态,ArchUnitTS 面向 TS/JS 生态,选型时应与团队技术栈匹配(仓库文档仅作工具介绍,具体版本与兼容性需在使用前自行核实)。

用 AI/LLM 充当 Fitness Function

文档还探讨了一个前沿用法:fitness function 可以借助 AI LLM 来评估决策——通过向模型提问,让其检查你的计划、代码、schema、API 等产物是否遵循了既定决策。文档给出了一段可直接复用的提示词模板:

IMPORTANT: Prefer retrieval-led reasoning over pre-training-led reasoning. IMPORTANT: Turn on extended thinking. Turn on expert advice. Turn on search. This is a fitness function to evaluate if our work is using all our decisions, and is correct and accurate. - Our decisions are here: {url} - Our work to evaluate is here: {url} Explain any errors, problems, gaps, weaknesses. Be direct. Be decisive.

这段模板的使用要点:

  • 开启检索优先推理(retrieval-led reasoning):明确要求模型以提供的资料(决策文档 URL、工作产物 URL)为准,而不是依赖预训练记忆,减少幻觉;
  • 开启扩展思考、专家建议与搜索:提示模型调用更强的推理模式;
  • 提供两个输入:{url}分别填入"决策所在位置"(如 ADR 目录)与"待评估的工作"(如 PR、设计文档、API schema);
  • 输出要求:直接、果断地指出错误、问题、缺口与弱点,而非泛泛而谈。

这种用法把 fitness function 从"确定性断言"扩展到了"语义级审查":适合评估文档一致性、决策覆盖率、接口设计与决策的契合度等难以用传统断言表达的场景。其本质仍是"客观检查 + 持续运行",只是检查器由代码换成了 LLM。

从"记录"到"强制执行":Pull Request 上的决策护栏

在仓库的主索引页中,紧接 fitness functions 之后的进阶主题是"决策的 Pull Request 护栏(Decision guardrails for pull requests)",它与 fitness function 是同一目标的不同实现路径:

  • Decision Guardian:在开发者正在修改决策所覆盖的代码时,自动在 PR 上浮现相关的决策记录,让上下文在合并前直达开发者眼前,适用于架构、数据、合规、临床医疗、安全等各类决策,可配合 GitLab、Jenkins、CircleCI 等任意 CI 系统,也可作为 pre-commit 钩子使用;
  • ADR Guard:GitHub Action,当被监视的代码路径发生变更却没有新增或更新 ADR 时,直接让 PR 失败;同时支持显式豁免(在 PR 中写入带理由的ADR-Exempt:行即可通过关卡,理由会被写入 job summary)。

这两类工具与 fitness function 的关系可理解为互补:fitness function 验证"代码是否符合决策",PR 护栏验证"改动是否带了决策记录"。仓库自带的 architecture-decision-record-skill 在"可选:接入 Pull Request"一节中也提到了这两个工具,说明项目整体把"决策自动化保障"视为 ADR 实践闭环的重要部分:写决策 → 固化为可测试代码 → 在 PR/CI 处强制执行。

仓库中的相关资源与延伸阅读

围绕本文主题,你可以在当前仓库中继续深入:

  • 本文主体文档:fitness-functions-for-decisions-as-code/index.md
  • 概念基础:what-is-an-architecture-decision-record/index.md(ADR、ADL、ASR 等术语定义)
  • 决策落地示例:continuous-integration/index.md、choosing-a-database-technology/index.md
  • 使用 git 开始 ADR 实践:how-to-start-using-adrs-with-git/index.md
  • 可持续决策的相关标准与指南:decision-sustainability-criteria、guidelines-to-achieve-sustainable-decisions
  • 全量索引(含 fitness functions 与 decision guardrails 章节):locales/en-001/index.md
  • 含 PR 护栏工具说明的技能文档:architecture-decision-record-skill/SKILL.md

小结

Fitness functions for decisions as code 提供了一条把架构决策从"文档"推向"代码"的路径:决策记录负责回答"为什么",fitness function 负责回答"是否仍然成立"。通过客观的通过/失败结果、随每次提交与构建持续运行、在重构时自动捕获违规、以及用自动化替代人工审查实现规模化治理,它让 ADR 真正成为团队可执行、可验证、可演进的质量基础设施。无论是用 ArchUnit/ArchUnitTS 做架构单元测试,还是用 LLM 提示词做语义级审查,抑或配合 PR 决策护栏强制执行,其目标一致:让每一项重要决策都"活"在代码里。

【免费下载链接】architecture-decision-record

Architecture decision record (ADR) examples for software planning, IT leadership, and template documentation

项目地址:https://gitcode.com/gh_mirrors/ar/architecture-decision-record
点击查看免费下载
上一篇:Django REST framework文档生成终极指南:10分钟学会自动创建API文档
下一篇:Flink Python Table API 入门教程:用纯 Python 构建词频统计(Word Count)管道

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询