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 用两样东西填补了这个空白:

  1. 一致的缩放。 arc42 的构建块视图本身就有层级:第 1 层是"整个系统的白盒描述,以及其中所有构建块的黑盒描述",第 2 层则"放大第 1 层中的部分构建块"(第 5 章)。C4 的层级为这些缩放步骤赋予了固定含义(系统、容器、组件、代码),所以懂 C4 的读者在读标签之前就知道自己在看什么。
  2. 一套小而共享的词汇。 人员、软件系统、容器、组件、关系,每个都有名称、描述,通常还有技术。这些记法足以让不同团队的图可以相互比较,又少到没人需要培训。

还有一个实际的好处。如果 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 动态图指南 | 软件架构文档模板