arc42 vs C4 模型:区别以及如何结合使用
团队里有人提议用 arc42 来写架构文档,另一个人说团队已经在用 C4 了。接下来的讨论通常默认你必须二选一,而这正是首先要抛弃的假设。
比较 arc42 和 C4,有点像比较一份报告的提纲和放进报告里的图表。arc42 是一个模板:十二个章节告诉你关于一个架构应该记录什么,从质量目标到风险。C4 是一种模型和记法:四个层级的图告诉你如何画出一个软件系统的结构。它们在少数地方有重叠,而且可以很好地结合。本指南介绍两者各自涵盖的内容、arc42 要求而 C4 不画的内容、C4 为 arc42 增加了什么,以及一张逐章节的对照表,说明哪张 C4 图该放在哪里。
一句话回答
arc42 是架构文档的模板。C4 模型是绘制软件架构图的方法。同时使用两者的团队,大多把 C4 图放进 arc42 的章节里。
arc42 自己的 FAQ 也是这样描述两者关系的。对于"arc42 和 C4 是什么关系?"这个问题,它的回答是 C4 模型"与 arc42 的几个章节有_许多_相似之处,但省略了某些部分(例如质量需求、横切概念、风险以及其他几项)"(arc42 FAQ,B-17)。同一份 FAQ 还把 Simon Brown 的 C4 模型列为 arc42 的替代方案之一(A-6)——如果你只需要图,这没错;如果你还需要文档承载的其他一切,这就会产生误导。
| arc42 | C4 模型 | |
|---|---|---|
| 是什么 | 用于记录和沟通软件架构的模板 | 用于绘制软件架构图的分层模型和记法 |
| 作者 | Peter Hruschka 和 Gernot Starke,"自 2005 年起经过实践检验"(arc42.org) | Simon Brown |
| 形式 | 12 个章节,实际使用中全部可选 | 4 个核心层级(Context、Container、Component、Code)加上补充图 |
| 涵盖内容 | 目标、约束、上下文、结构、运行时、部署、概念、决策、质量、风险、术语表 | 四个缩放层级上的静态结构,以及运行时(动态)视图和部署视图 |
| 记法 | 不作规定 | 由少量元素类型构成的方框和箭头,每张图附图例 |
| 产出 | 一份文档(AsciiDoc、Markdown、Word、Confluence 等),CC BY-SA 4.0 | 手工绘制或由模型生成的图 |
arc42 的十二个章节
在做任何映射之前,先把各章节及其确切编号放在眼前会很有帮助。以下内容来自 arc42 文档,模板版本 9.0(根据下载页面,发布于 2025 年 7 月):
| # | 章节 | 包含内容(arc42 自己的概述) |
|---|---|---|
| 1 | Introduction and Goals(引言与目标) | 需求、利益相关者、最重要的质量目标 |
| 2 | Constraints(约束) | 技术和组织约束、约定 |
| 3 | Context and Scope(上下文与范围) | 业务上下文和技术上下文、外部接口 |
| 4 | Solution Strategy(解决方案策略) | 设计背后的根本决策和思路 |
| 5 | Building Block View(构建块视图) | 源代码的抽象,黑盒与白盒 |
| 6 | Runtime View(运行时视图) | 运行时场景:构建块如何交互 |
| 7 | Deployment View(部署视图) | 硬件和技术基础设施、部署 |
| 8 | Crosscutting Concepts(横切概念) | 反复使用的方法和模式 |
| 9 | Architecture Decisions(架构决策) | 重要的、代价高的、有风险的或有争议的决策 |
| 10 | Quality Requirements(质量需求) | 质量需求概览和详细的质量场景 |
| 11 | Risks and Technical Debt(风险与技术债务) | 已知问题、风险和技术债务 |
| 12 | Glossary(术语表) | 重要业务术语和技术术语的定义 |
arc42 还明确说明了一件事:你不必把所有内容都填满。它的 FAQ 在回答"哪些部分是必需的?"时说:"请不要_把所有内容都填满_。只记录你的利益相关者需要的内容",因为你写下的一切"将来都可能需要维护投入"(B-1)。这条建议对下文的结合方式很重要:一份在三个章节里配有好 C4 图的精简 arc42 文档,胜过一份没人更新的完整文档。
arc42 涵盖而 C4 不涵盖的内容
C4 关注结构,并通过补充图涵盖运行时和部署。对于架构中那些不是方框的部分,它什么也没说。用 arc42 的术语来说,下面这些章节在 C4 中完全没有对应物:
- 第 1 章,Introduction and Goals(引言与目标)。 系统为什么存在,谁关心它,以及决定后续所有决策的三到五个质量目标。C4 上下文图展示谁在使用系统,却说不出"结账必须在两秒内完成"比"管理界面好看"更重要。
- 第 2 章,Constraints(约束)。 "必须运行在公司的 Kubernetes 平台上"、"必须用 Java 编写"、"数据不得离开欧盟"。约束解释了图只是呈现出来的那些选择。
- 第 4 章,Solution Strategy(解决方案策略)。 把少数几个根本性选择(先做单体、账本用事件溯源、搜索引擎直接采购)集中概括在一处。
- 第 8 章,Crosscutting Concepts(横切概念)。 认证、错误处理、日志、持久化模式、国际化。它们贯穿每一个方框,因此没有哪一个方框能单独展示它们。
- 第 10 章,Quality Requirements(质量需求)。 具体的质量场景:刺激、响应、度量。
- 第 11 章,Risks and Technical Debt(风险与技术债务)。 你知道哪里脆弱,以及你推迟了什么。
- 第 12 章,Glossary(术语表)。 业务中使用的词汇,一次性定义清楚。
这些正是 arc42 FAQ 说 C4"省略了某些部分"时所指的章节。如果你的架构文档只有 C4 图,新来的架构师或审计人员读完之后,仍然会带着这些问题。
C4 为 arc42 增加了什么
arc42 有意不规定记法。第 5 章要求"黑盒和白盒的分层集合",第 3 章建议使用"各种把系统作为黑盒展示的图",第 6 章则接受从带编号的步骤列表到时序图、BPMN 或状态机的任何形式(第 5 章、第 3 章、第 6 章)。这种灵活性是模板的优点,但也正是 arc42 文档最容易参差不齐的地方:每个作者的画法都不一样。
C4 用两样东西填补了这个空白:
- 一致的缩放。 arc42 的构建块视图本身就有层级:第 1 层是"整个系统的白盒描述,以及其中所有构建块的黑盒描述",第 2 层则"放大第 1 层中的部分构建块"(第 5 章)。C4 的层级为这些缩放步骤赋予了固定含义(系统、容器、组件、代码),所以懂 C4 的读者在读标签之前就知道自己在看什么。
- 一套小而共享的词汇。 人员、软件系统、容器、组件、关系,每个都有名称、描述,通常还有技术。这些记法足以让不同团队的图可以相互比较,又少到没人需要培训。
还有一个实际的好处。如果 C4 图来自模型而不是绘图工具,同一个元素就会以同一个名称出现在第 3、5、6、7 章中。arc42 对如何做到这一点没有任何主张,但正是这一点让各章节彼此一致。
对照表:哪张 C4 图放进 arc42 的哪个章节
这张对照表是我们根据 arc42 的章节定义和 C4 的图定义推导出来的。arc42 的 FAQ 并没有规定一种结合方式,而是指向社区中的示例(例如 bitsmuggler 的 arc42 + C4 示例仓库),各团队在最后一列所列的细节上做法也不尽相同。
| C4 图 | arc42 章节 | 为什么合适 | 需要注意 |
|---|---|---|---|
| System Context(第 1 层) | 3 Context and Scope,业务上下文 | arc42 要求把系统作为黑盒,连同它的所有通信伙伴一起展示,这正是 C4 上下文图的定义 | arc42 还要求技术上下文(通道和协议)。给箭头加上协议标签,或者加一张把每个伙伴对应到其通道的表格 |
| Container(第 2 层) | 5 Building Block View,第 1 层 | 第 1 层是整个系统的白盒,其中包含的构建块以黑盒形式呈现 | arc42 的构建块是"源代码的抽象",C4 的容器是可部署单元。对大多数基于服务的系统来说两者一致;如果是模块化单体,你的第 1 层可能是模块而不是容器 |
| Component(第 3 层) | 5 Building Block View,第 2 层 | 第 2 层打开选定的第 1 层构建块,这正是 C4 组件图对一个容器所做的事 | 只为需要的容器画。arc42 也说的是"选定的" |
| Code(第 4 层) | 5 Building Block View,第 3 层,或者不放 | 需要时允许更深的层级 | 通常按需从代码生成,比保存在文档里更好 |
| 动态图 | 6 Runtime View | arc42 需要构建块交互的具体场景;C4 动态图展示一个场景中带编号的交互 | arc42 说"描述大量场景_并不_重要"。挑选少数在架构上有意义的场景 |
| 部署图 | 7 Deployment View | 两者都按环境把软件构建块映射到基础设施上 | arc42 要求记录"所有相关环境",通常意味着每个环境一张部署图 |
| System Landscape | 没有专门章节。通常放在附录,或放在 arc42 文档之外 | arc42 记录的是一个系统,而全景图跨越多个系统 | 如果需要,链接到一张共享的全景图,而不是把它复制到每个系统的文档里 |
| 架构决策记录(不是 C4 图) | 9 Architecture Decisions | arc42 自己就建议"为每个重要决策写一条 ADR(架构决策记录)",采用 Nygard 的结构(第 9 章) | arc42 也允许在决策所影响的构建块中就地记录。选定一种约定,并在第 9 章中维护一份索引 |
表中没有列出的章节(1、2、4、8、10、11、12)是文字和表格,而不是 C4 图。这不是哪一种方法的缺陷,而是分工。
实战示例
下面是把两者结合用于我们 C4 模型完整指南 中电商系统的样子:一个 React 单页应用、一个 API 网关、处理订单、商品和用户的 Go 服务、PostgreSQL 数据库、Kafka 以及一个通知服务。这不是一份完整的文档,而是一个放好了 C4 图的精简 arc42 骨架。
1. Introduction and Goals(引言与目标)
- 目的:顾客浏览并订购商品;仓库员工管理库存
- 质量目标:(1) 结账在 p95 下 2 秒内完成
(2) 没有成功的支付授权,任何订单都不会被确认
(3) 新增服务无需改动现有服务
2. Constraints(约束)
- 运行在公司的 Kubernetes 平台上;后端服务使用 Go
3. Context and Scope(上下文与范围)
- 业务上下文:C4 系统上下文图
[Customer], [Warehouse Staff] -> [E-Commerce Platform]
-> [Stripe], [FedEx API], [SendGrid]
- 技术上下文:伙伴 / 协议 / 交换数据的表格
4. Solution Strategy(解决方案策略)
- 每个服务一个数据库;通知通过 Kafka 异步发送
5. Building Block View(构建块视图)
- 第 1 层:C4 容器图(SPA、API Gateway、Order/Product/User
服务、三个 PostgreSQL 数据库、Kafka、Notification Service)
- 第 2 层:仅 Order Service 的 C4 组件图
(Order Handler、Order Service、Order Repository、Payment Client、
Inventory Client)
6. Runtime View(运行时视图)
- "顾客下单":C4 动态图,10 个编号步骤
7. Deployment View(部署视图)
- 生产环境:C4 部署图
- 预发布环境:只写与生产环境的差异
8. Crosscutting Concepts(横切概念)
- 在网关处认证;POST /orders 使用幂等键;
带请求 ID 的结构化日志
9. Architecture Decisions(架构决策)
- ADR-001 每个服务一个数据库
- ADR-002 订单事件使用 Kafka,而不是同步调用
- ADR-003 先授权支付,再写入订单
10. Quality Requirements(质量需求)
- 场景:促销期间每分钟 500 次结账,p95 低于 2 秒
11. Risks and Technical Debt(风险与技术债务)
- 库存在支付前预留;支付失败时尚无补偿机制
12. Glossary(术语表)
- 订单、预留、授权、履约
注意这些图放在哪里:第 3、5、6、7 章。其余部分都只是几行文字。再注意第 11 章的风险和第 9 章的 ADR-003,它们指向的正是第 6 章动态图所展示的同一件事。这种相互引用,正是 arc42 与 C4 结合的文档体现价值的地方:图展示步骤的顺序,ADR 说明原因,风险指出仍然存在的问题。
关于动态图本身,C4 动态图指南一步一步地讲解了这个场景。关于第 9 章,架构决策记录完整指南介绍了 arc42 推荐的格式以及如何维护索引。
如果你觉得 arc42 的十二个章节超出了团队的需要,我们的软件架构文档模板是基于同样理念的一份更短的 Markdown 提纲,其中有一节专门说明它如何对应回 arc42。
让两者都保持最新
arc42 和 C4 有一个共同的失败模式:两者在写成的那一天都很出色。arc42 自己的 FAQ 也警告说,你填写的每一个章节都是你签下的维护承诺(B-1)。以下是一些经得起时间考验的习惯:
- 尽量不要把图放进文档正文。 引用或嵌入从模型生成的图,而不是粘贴截图。容器图的截图在容器改名的那天就过时了;从模型渲染的图,只会和模型一样新或旧。
- 把变化快的章节放在代码旁边。 第 5、6、9 章随代码变化,第 1、2、10 章随业务变化。把前一组放进代码仓库(arc42 为此提供了 Markdown 和 AsciiDoc 模板),就能通过拉取请求来更新它们。
- ADR 只往前写,永不修改。 被取代的决策就写一条新的 ADR。第 9 章因此成为一段历史,而不是一个被改写的故事。
- 给每个章节指定负责人和评审日期。 没有负责人的文档,就是没人更新的文档。
- 用代码核对与结构相关的章节。 第 3 章和第 5 章描述的是代码中存在的东西,所以可以自动检查。第 1、8、10 章则不行,需要有人按计划评审。
最后一点正是 archyl 的用武之地,而且只针对问题的一部分。archyl 保存的是 C4 模型,而不是 arc42 文档。它的 AI 发现会从代码仓库中提出系统、容器、组件和关系,由你审批;ADR 关联到它们所影响的 C4 元素上;漂移评分则检查文档中的元素是否仍然存在于代码中。这覆盖了以图为主的章节(3、5、6、9)。它不会替你写质量目标、横切概念或风险清单,也没有 arc42 导出功能;文字章节仍然留在你的 arc42 文档中,并链接到模型。
常见问题
arc42 比 C4 好吗?
两者没有优劣之分,因为它们做的不是同一件事。arc42 是一个文档模板,涵盖目标、约束、结构、运行时、部署、决策、质量和风险。C4 是一种一致地画出结构的方法。如果你需要一份完整的架构文档,就用 arc42(或类似结构的东西);如果你需要一致的图,就用 C4。两者都需要的团队,大多在 arc42 中使用 C4 图。
arc42 和 C4 可以一起用吗?
可以,而且很常见。arc42 不规定记法,所以 C4 图可以直接放进它的章节:上下文图放在第 3 章,容器图和组件图放在第 5 章,动态图放在第 6 章,部署图放在第 7 章。
C4 容器图放在 arc42 的哪里?
放在第 5 章 Building Block View 的第 1 层,也就是整个系统的白盒视图。组件图放在第 2 层,只为需要的容器画。如果你的系统是模块化单体,第 1 层的构建块可能是模块而不是容器,对应关系会更松散。
arc42 要求使用 UML 吗?
不要求。arc42 在几个章节中建议了记法(例如第 3 章提到可以用 UML 部署图表示技术上下文),但选择权在你。C4、UML 以及简单的方框加箭头,都有人与它搭配使用。
在 arc42 中 ADR 放在哪里?
放在第 9 章 Architecture Decisions。arc42 自己建议为每个重要决策采用 Michael Nygard 的结构写一条 ADR;如果那样更易读,也允许在决策所影响的构建块中就地记录。
arc42 是免费的吗?
是的。该模板免费且开源,采用 CC BY-SA 4.0 许可,提供十二种语言版本以及 AsciiDoc、Markdown、Word、Confluence 等多种格式(下载页面)。
想让 arc42 文档中的 C4 部分始终与代码保持一致?免费试用 archyl,从你的代码仓库生成模型。继续阅读:什么是 C4 模型?完整指南 | 架构决策记录:完整指南 | C4 动态图指南 | 软件架构文档模板