mcpField
A
arch-fitness-functions

arch-fitness-functions

github.com/yonatankarp测试与质量139 次安装23 周前更新
代码仓库

关于 arch-fitness-functions

面向希望通过自动检查维持架构决策的团队的指南,介绍在 CI 或生产环境运行的架构适应度函数,涵盖依赖规则、层边界和性能属性。

主要功能

  1. 01架构规则自动化检查
  2. 02CI 构建失败时阻止违规
  3. 03静态与动态检查
  4. 04依赖方向与层边界验证
  5. 05生产性能属性监测

适用场景

  1. 01持续执行架构决策
  2. 02防止模块依赖方向偏离
  3. 03约束迁移项目的新代码

安装

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

$npx skills add https://github.com/yonatankarp/software-design-skills --skill arch-fitness-functions

安装后在 Claude Code 中输入/arch-fitness-functions确认已加载。

详细介绍

一句话总结

将架构意图编码为自动化检查,并在每次变更时运行。如果架构规定“领域层不依赖 Spring”,那么一旦违反,适应度函数就会使构建失败。

何时使用此技能

  • 某项架构决策至关重要,需要随着时间推移始终成立(依赖方向、层边界、无循环依赖、性能预算)。
  • 团队规模足够大,仅靠口头约定“我们说好不做 X”无法确保所有 PR 都遵守。
  • 迁移项目(arch-strangler-fig),需要确保新代码采用新的结构,而不是沿用旧结构。
  • 任何原本需要依靠代码审查来发现架构偏移的架构决策。

何时不使用此技能

  • 项目很小,只有一名开发者,也没有扩展性问题。
  • 架构属性确实主观,无法自动化(例如品味、审美、边缘情况下的命名风格)。
  • 过度管控——每条架构规则都有成本;只强制执行那些你愿意据此拦截 PR 的规则。

核心内容

适应度函数是一种用于断言架构属性的测试。与单元测试一样,它们会:

  • 在 CI 中随每次变更自动运行。
  • 违反规则时使构建失败。
  • 以可执行的形式记录架构意图。

适应度函数的类别(Ford、Parsons、Kua,Building Evolutionary Architectures):

  • 原子型与整体型。 原子型检查单一属性(此模块中没有循环依赖)。整体型结合多个属性(负载下的性能与正确性)。
  • 触发型与持续型。 触发型在每次构建时运行(最实用)。持续型在生产环境中运行(延迟预算、错误率)。
  • 静态型与动态型。 静态型分析代码(依赖方向)。动态型运行系统(响应时间检查)。

常见的静态适应度函数(最适合作为入门选择):

  • 依赖方向。 “模块 X 不得依赖模块 Y。”通过构建图或专用库强制执行(JVM 使用 ArchUnit,TypeScript 使用 ts-arch,JS 使用 dependency-cruiser)。
  • 无循环依赖。 检测因导入位置不当而意外引入的循环依赖。
  • 命名约定。 “controller/ 中的每个类都必须以 Controller 结尾。”大多只是表面规范,但实施成本低。
  • 公共 API 稳定性。 “此接口上新增公共方法时,必须有对应的测试。”可通过自定义检查实现。
  • 层边界违规。 “domain/ 中的代码不得导入 infrastructure/ 中的内容。”这是经典的六边形架构检查。

用于生产架构的动态适应度函数:

  • p99 延迟低于阈值。
  • 限制内存用量。
  • 确保特定业务不变量成立(余额不为负;订单不重复)。

ArchUnit 示例(JVM,生态最成熟):

@ArchTest
val domainHasNoSpringDependencies =
    noClasses().that().resideInAPackage("..domain..")
        .should().dependOnClassesThat().resideInAPackage("org.springframework..")

决策启发

  • 从一两个用于强制执行最重要架构属性的适应度函数开始(通常是依赖方向)。随着架构偏移问题逐渐显现,再逐步添加。
  • 让适应度函数失败时使构建失败——被忽略了一年的警告,不算适应度函数。
  • 将适应度函数视为测试:每个函数都应有清晰的失败消息,解释规则为何存在,而不只是检查什么。
  • 不要为你不会据此拦截 PR 的规则编写适应度函数。
  • 对于迁移项目,适应度函数可以编码“新代码必须放在路径 X 中,而不是旧路径 Y 中”——这对确保迁移按计划进行至关重要。

反模式

  • 无人负责的适应度函数。 出问题 → 有人将其禁用 → 从此一直被绕过。
  • 过度监管。 数百个适应度函数强制执行每项偏好。CI 变慢;开发者学会忽略失败。
  • 把风格当作架构。 “所有方法名都必须使用 camelCase”是 lint 规则,不是适应度函数。不要滥用这个术语。
  • 只有文档,没有自动化。 Wiki 页面描述了架构;没有自动化检查;新成员几周内就会违反约定。
  • 一次性检查。 只做一次架构审计,然后把结果归档。之后架构漂移立即开始累积。

另请参阅

  • arch-layered — 层边界是适应度函数的典型用例。
  • arch-hexagonal — 依赖关系指向领域,是典型的六边形架构适应度函数。
  • arch-adr — 适应度函数编码的是是什么;ADR 解释的是为什么。两者应配合使用。

参考资料

  • Neal Ford、Rebecca Parsons、Patrick Kua,Building Evolutionary Architectures(O'Reilly,第 2 版)——奠基性参考资料。
  • ArchUnit 文档(JVM)。
  • Richards 和 Ford,Fundamentals of Software Architecture,治理 / 适应度章节。

评论

支持 Markdown