# 03 · 读懂与画好架构图(C4 模型) > 上一章你学会了把系统想清楚。这一章解决下一个问题:**怎么把脑子里那个系统,画成别人一眼就懂的图。** 架构师一大半的工作不是设计,而是沟通——而图,是沟通的主力工具。 --- ## 为什么架构师必须会画图 先纠正一个误解:画架构图,**不是为了好看,也不是为了交差**,而是为了一件最朴素的事——**让别人和你看到的是同一个系统。** 想象一下:你脑子里那个系统是清晰的,数据怎么流、谁依赖谁、边界在哪,你门儿清。但**它锁在你脑子里。** 你的产品经理不知道,后端同事各有各的理解,前端以为是另一回事。于是十个人,脑子里装着十个略有不同的系统——**这是几乎所有项目混乱的根源。** 架构图的作用,就是把你脑中那个系统**「倒」出来,摆到桌面上**,让所有人对着同一张图说话。它的价值,在于「**对齐**」: ``` 没有图: 有图: 产品脑中 后端脑中 所有人 的系统 的系统 看着同一张 │ │ 图说话 ▼ ▼ │ 「我以为」 「我以为」 ▼ ↘ ↙ 「我们说的 冲突、返工 是同一个东西」 ``` > **一句话:架构师的产出,不只是「想清楚」,还得是「让团队都清楚」。** 想清楚了却讲不明白,在团队协作里,几乎等于没想清楚。会画图,是把个人的判断力,变成团队的共识——这是架构师的核心工作,不是附加技能。 而且,**画图本身就是一种思考。** 当你试图把脑中的系统画下来,常会发现「咦,这两个东西到底谁调谁?」「这里的边界其实我没想清楚」——**图会逼你把含糊的地方想明白。** 画不出来,往往就是还没想清楚的信号。 --- ## 先看看「烂图」长什么样 在学怎么画好之前,先认认坏味道。你一定见过这种图:一堆五颜六色的方块,密密麻麻的箭头横七竖八,看半天不知道它想说什么。**烂图比没有图更糟,因为它制造一种「我们沟通过了」的错觉,实际上每个人理解的还是不一样。** 烂图通常犯这几个毛病: ``` ┌─────────────────────────────────────────────────────────────┐ │ 烂图四宗罪 │ ├─────────────────────────────────────────────────────────────┤ │ ① 没有边界 所有框平铺在一起,分不清哪些在一个进程/ │ │ 一台机器/一个信任域里。 │ │ │ │ ② 箭头没方向 线就是线,不知道是 A 调 B 还是 B 调 A, │ │ 也不知道线上跑的是什么(数据?调用?事件?) │ │ │ │ ③ 抽象层次混乱 一张图里,「整个支付系统」和「某个工具函数」 │ │ 画在同一层。大小不一的概念混在一起,看的人 │ │ 不知道该用什么颗粒度理解。 │ │ │ │ ④ 框太多 四十个方块挤在一页,信息量爆炸, │ │ 看的人直接放弃。 │ └─────────────────────────────────────────────────────────────┘ ``` 第三条「抽象层次混乱」最隐蔽,也最致命,值得多说一句。**它就像一张地图上,既画了「整个中国」,又画了「你家小区的某栋楼」**——这两个东西的尺度差了十万八千里,放在一起,看的人完全不知道该站在多高的视角去理解。 好图的反面,正是治好这四宗罪:**有清晰的边界、箭头标明方向和含义、一张图只用一个抽象层次、框的数量受控。** 那么,有没有一套现成的方法,能帮我们系统地做到这些?有,它叫 **C4 模型**。 --- ## C4 模型:像用地图软件一样,分层级看系统 C4 模型的核心思想,**和你用地图软件的体验一模一样。** 你查路线时,不会用同一个缩放级别看完所有东西:**先看「中国地图」**知道城市在哪,**放大到「市区图」**看主干道,**再放大到「街道图」**看具体怎么走。**每一层只显示那一层该有的信息,多一分则乱,少一分则空。** C4 把架构图也分成这样四个「缩放级别」,从最宏观到最微观: ``` 缩放级别 C4 层次 画的是 给谁看 🌍 中国地图 → ① Context 上下文 整个系统 + 周边 所有人 (用户、外部系统) (含非技术) │ ▼ 放大,钻进「我们的系统」内部 🏙️ 市区图 → ② Container 容器 系统由哪几个 技术团队 「可独立运行的 (架构、运维、 大块」组成 技术负责人) │ ▼ 放大,钻进「某一个容器」内部 🛣️ 街道图 → ③ Component 组件 一个容器内部 开发这块的 由哪些模块组成 工程师 │ ▼ 放大,钻进「某一个组件」内部 🏠 楼栋图 → ④ Code 代码 类、函数怎么组织 (基本不画, 交给 IDE) ``` > C4 这个名字,就来自这四层的英文首字母:**C**ontext、**C**ontainer、**C**omponent、**C**ode。 > > 它最大的贡献,是直接根治了烂图的第三宗罪——**「抽象层次混乱」。** 因为它强制你:**一张图,只待在一个缩放级别上。** 你要么画整个系统的全貌,要么钻进某一块看它内部,**绝不在一张图里混着画。** 下面逐层看。**重点掌握前两层(Context 和 Container)**,因为它们是日常用得最多、也最能体现架构判断的两层。 ### 第①层:Context(系统上下文)—— 给所有人看 这是缩放到最远的一层。在这张图里,**你的整个系统就是中间一个框**(对,整个系统就一个框,内部细节一概不画),周围画的是:**谁在用它**(用户、各种角色)、**它要和哪些外部系统打交道**(支付网关、邮件服务、第三方登录……)。 它回答的是最高层的问题:**「这个系统是干嘛的?它和外面的世界怎么交互?」** ``` Context 图示例:一个「在线书店」 ┌──────────┐ ┌──────────────┐ │ 顾客 │ │ 出版社系统 │ │ (用户) │ │ (外部,供货) │ └────┬─────┘ └──────▲───────┘ │ 浏览、下单 │ 同步库存 ▼ │ ┌─────────────────────────────────────────┴────┐ │ │ │ 在 线 书 店 系 统 │ │ (我们要做的东西,内部先不展开) │ │ │ └──────┬──────────────────────────┬─────────────┘ │ 发起支付 │ 发送订单邮件 ▼ ▼ ┌──────────────┐ ┌──────────────┐ │ 支付网关 │ │ 邮件服务 │ │ (外部) │ │ (外部) │ └──────────────┘ └──────────────┘ ``` **给谁看:所有人,包括产品经理、老板、客服——任何不写代码但需要理解「这系统在生态里扮演什么角色」的人。** 这张图的妙处是,它一个技术名词都没有,**非技术的人也能看懂**,所以特别适合用来对齐「我们到底在做什么」。 ### 第②层:Container(容器)—— 给技术团队看 把上一层中间那个「整个系统」的框**放大、钻进去**,你看到的就是 Container 层。 这里的「Container(容器)」**不是指 Docker 那种容器**(别被名字骗了)。在 C4 里,它指的是「**一个可以独立运行、独立部署的大块**」——比如一个前端应用、一个后端服务、一个数据库、一个缓存。**判断标准很简单:它是不是一个能单独启动、单独部署的进程或存储?** 是,它就是一个 Container。 这一层回答:**「我们的系统,内部由哪几个能独立运行的大块组成?它们之间怎么通信?数据存在哪?」** ``` Container 图示例:把上面那个「在线书店系统」放大 ┌──────────┐ │ 顾客 │ └────┬─────┘ │ HTTPS ▼ ┌─────────────────────────────────────────────────────────┐ │ 在线书店系统(虚线 = 系统边界,框内都是「我们的」) ┊ ┊ ┊ ┊ ┌──────────────┐ 调用 API ┌───────────────┐ ┊ ┊ │ Web 前端 │ ─────────────────▶ │ 后端服务 │ ┊ ┊ │ (浏览器应用) │ ◀───────────────── │ (处理业务逻辑) │ ┊ ┊ └──────────────┘ 返回 JSON └───┬───────┬───┘ ┊ ┊ │ │ ┊ ┊ 读写订单/商品 │ │ 缓存热门商品 ┊ ▼ ▼ ┊ ┊ ┌──────────┐ ┌────────┐ ┊ ┊ │ 数据库 │ │ 缓存 │ ┊ ┊ └──────────┘ └────────┘ ┊ └──────────────────────────────────────────────────────────┘ ``` **给谁看:技术团队——架构师、技术负责人、运维。** 因为这一层直接对应「部署」和「运维」:每个 Container 通常就是一个要部署、要监控、可能要扩容的单元。**这也是架构判断最密集的一层**——「拆成几个服务」「数据库怎么分」「要不要加缓存」,这些上一章讲的取舍,大多体现在这张图上。 > 💡 **你或许注意到了:本仓库每个模板的「架构全景图」,基本就画在 Container 这个层次。** 比如 [AI 对话产品模板](../templates/ai-chat-product/README.md) 的第 4 节那张图,里面的「接入层、编排层、推理服务、会话存储、向量检索」,每一个都是一个可独立运行的大块——这就是一张典型的 Container 图。**学会读 Container 图,你就能读懂本仓库几乎所有的全景图。** ### 第③层:Component(组件)—— 给开发这块的人看 再放大,钻进**某一个 Container**(比如上面的「后端服务」),看它内部由哪些模块构成——比如「订单模块」「商品模块」「用户认证模块」,以及它们怎么协作。 ``` Component 图示例:把「后端服务」这一个容器放大 ┌──────────────────────────────────────────────────┐ │ 后端服务(放大看它内部) │ │ │ │ ┌────────────┐ ┌────────────┐ │ │ │ 订单模块 │ ───▶ │ 库存模块 │ │ │ └─────┬──────┘ └─────┬──────┘ │ │ │ │ │ │ ▼ ▼ │ │ ┌────────────┐ ┌────────────┐ │ │ │ 支付对接 │ │ 数据访问层 │ ──▶ (到数据库) │ │ └────────────┘ └────────────┘ │ └────────────────────────────────────────────────────┘ ``` **给谁看:要开发这个 Container 的工程师。** 它帮一个团队内部就「这块代码怎么分模块、谁负责谁」达成一致。**注意:只有当某个 Container 复杂到值得拆解时,才需要画它的 Component 图——简单的就别画了。** ### 第④层:Code(代码)—— 通常不画 最后一层,是具体到类、函数怎么组织。 **说实话,这一层基本不用手画。** 因为代码本身、以及 IDE 自动生成的关系图,就是最准确、最实时的「Code 图」——你手画一张,代码一改它就过时了。**所以 C4 模型自己都说:Code 层按需偶尔画一下即可,绝大多数时候跳过。** > 这本身就是个朴素的工程智慧:**别去手工维护一份「代码一改就过时」的文档。** 你的精力,该花在 Context 和 Container 这种「相对稳定、又最需要沟通」的层次上。 --- ## 画图的基本元素:就三样 C4 看着花哨,但你手里真正的「画笔」其实只有三样东西。**把这三样的含义钉死,你的图就不会乱。** ``` ┌─────────┐ │ 框 │ = 一个「有职责的东西」。 └─────────┘ 它得能回答「你是干嘛的」。一个系统、一个服务、 一个模块都行,但同一张图里,所有框的「尺度」要一致。 ───▶ = 箭头 = 一段「关系」。 关键:① 一定有方向(谁主动找谁); ② 一定标含义(线上跑的是「调用」?「数据」?「事件」?) 没方向、没含义的线,是烂图的头号来源。 ┌ ─ ─ ─ ─ ┐ ┊ 边界 ┊ = 一条「分界线」。 └ ─ ─ ─ ─ ┘ 圈住「属于一起的东西」。它可能是: • 部署边界(这些跑在同一台机器/集群里) • 信任边界(框内是我们可信的,框外的输入都不可信) • 系统边界(哪些是「我们的」,哪些是外部的) ``` 这三样里,**新人最常忽略「边界」,而它恰恰最能体现架构思维。** 一条边界,常常同时意味着「部署在哪」和「信任到哪」——比如上一章那个 AI 模板里反复强调的「**任何重新进入系统的外部数据都不可信**」,在图上,就是一条把「我们的系统」和「外部输入」分开的信任边界。**边界画在哪,往往就是安全和部署决策的所在。** --- ## 几条能立刻让你的图变好的原则 把这五条记下来,贴在显示器边上。它们直接对治前面说的「四宗罪」: 1. **一张图,只用一个抽象层次。** 这是 C4 的灵魂,也是最重要的一条。别在画整个系统的图里,突然塞进一个具体函数。**要么都是「大块」,要么都是「模块」,不许混。**(治第③宗罪) 2. **箭头一定标方向和含义。** 每根线都要能回答两个问题:「谁找谁?」「为了什么?」。在线旁写上「调用 API」「读写数据」「发送事件」之类的几个字。**一根没标注的线,就是一个没想清楚的依赖。**(治第②宗罪) 3. **控制框的数量(7±2)。** 人一眼能抓住的东西大约就 7 个上下。**一张图超过 9 个框,就该考虑:是不是该往上抽一层、或者拆成两张图了。** 信息要分层喂,不是一次性砸过去。(治第④宗罪) 4. **先画 Context,再往下钻。** 永远从最宏观的那张图开始,确认「系统和外界的关系」对齐了,**再**钻进去画 Container。**自顶向下,别一上来就陷进某个组件的细节里**——那样你很容易只见树木不见森林。 5. **图是给人看的,不是给机器看的。** 时刻问自己:「我的读者是谁?他需要这个信息吗?」给老板看的 Context 图里别出现技术黑话;给工程师看的 Container 图别为了简洁省掉关键的数据流。**永远为你的读者画图。** --- ## ASCII 画图实用技巧 本仓库统一用纯文本(ASCII)画图——因为它在任何地方都能显示、能直接放进 Markdown 和代码注释、还能用文本 diff 看出改了什么,**朴素但极其实用。** 这里给你几个上手的小技巧: ``` ① 框:用方块字符围起来 ┌─────────┐ 横线 ─ 竖线 │ 四个角 ┌ ┐ └ ┘ │ 服务 A │ 交叉 ┼ 丁字 ┬ ┴ ├ ┤ └─────────┘ ② 箭头:标清方向 ──▶ ◀── ▲ ▼ 单向依赖 ◀──▶ 或上下各一条 双向交互(如「请求/响应」) ③ 边界:用虚线和实线区分 ┌─────────┐ 实线框:一个具体的东西 └─────────┘ ┌ ─ ─ ─ ─ ┐ 虚线框:一条边界(系统/信任/部署) ┊ ┊ └ ─ ─ ─ ─ ┘ ④ 在箭头旁边加文字,说明这根线在干嘛(最重要!) A ───调用 API───▶ B A ◀──返回结果──── B ``` 几个小提醒: - **先在草稿纸或白板上画,想清楚布局再誊成 ASCII。** ASCII 改起来不如随手画的方便,所以「先想后画」更重要。 - **善用对齐和留白。** 把同一层的框横向对齐、纵向拉开,图会清爽很多。挤在一起的 ASCII 图,可读性会断崖式下降。 - **不必追求像素级完美。** ASCII 图的目标是「**讲清结构和关系**」,不是当艺术品。能让人看懂数据怎么流、谁依赖谁,就成功了。 > 你不用从头死记这些字符。**最好的学法,是直接去本仓库的模板里「抄」**——看 [AI 对话产品模板](../templates/ai-chat-product/README.md) 的全景图怎么用框和箭头,照着模仿,几次就熟了。 --- ## 动手练一练 光看不练,学不会画图。给你一个具体的练习,**强烈建议真的动手做一遍:** > **练习:** > 1. 打开 [`../templates/`](../templates/README.md),挑**任意一个**你感兴趣的系统(比如电商、社交信息流、实时通讯……)。 > 2. **先别看它的全景图!** 只读它开头的「一句话定位」和「核心需求」,然后**自己动手**,画一张它的 **Context 图**:中间一个框是这个系统,周围是用户和它要打交道的外部系统。用纸笔或 ASCII 都行。 > 3. 画的时候,刻意应用本章的原则:框是不是只用了一个抽象层次?箭头有没有标方向和含义?有没有圈出系统边界? > 4. 画完,再去对照模板里的**架构全景图**(那是一张 Container 图)。 对照时,重点体会两件事: - **你的 Context 图(最远的视角)和它的 Container 图(钻进去一层),是不是正好差了一个「缩放级别」?** ——感受 C4 分层的威力:你画的「整个系统一个框」,放大进去,就是模板里那一堆相互协作的大块。 - **模板全景图里,有没有你没想到的「外部系统」或「内部大块」?** 它为什么需要那个东西?——这一问,又回到了第 02 章的「**为什么**」。**画图不只是画图,它逼着你重新理解这个系统的每一个决策。** --- ## 📌 真实案例:C4 模型不是我们发明的 本章用的 C4 模型,来自 **Simon Brown** 提出的同名方法论,如今是业界画架构图的事实标准之一。 - 📎 官方:[c4model.com](https://c4model.com) —— 有更完整的四层定义、记号约定和大量真实示例。 - 本仓库 25 个模板的全景图,基本都画在 C4 的 **Container 层**——学会读它,就能读懂仓库里几乎所有系统。 --- ## 🎯 随堂检验 --- ## 本章小结 - **画图的本质是「对齐」**,让团队所有人看到同一个系统。架构师一大半的工作是沟通,图是沟通的主力工具;想清楚却讲不明白,约等于没想清楚。**而且画图本身会逼你把含糊处想透。** - **烂图四宗罪:没边界、箭头没方向、抽象层次混乱、框太多。** 其中「抽象层次混乱」最致命——就像一张地图既画整个国家又画你家楼栋。 - **C4 模型像地图软件的缩放级别**,分四层:**Context**(整个系统+周边,给所有人)→ **Container**(可独立运行的大块,给技术团队)→ **Component**(容器内的模块,给开发者)→ **Code**(基本不画)。它的灵魂是:**一张图只待在一个缩放级别。** - **本仓库的全景图,基本都是 Container 层的图。** 学会读它,就能读懂仓库里几乎所有系统。 - **画图的画笔只有三样:框(有职责的东西)、箭头(标方向和含义的关系)、边界(部署/信任/系统的分界)。** 新人最易忽略边界,而它最能体现架构思维。 - **五条原则**:一张图一个抽象层次、箭头标方向和含义、控制框数(7±2)、先 Context 再下钻、永远为你的读者画图。 --- > 到这里,**第一段「建立思维」就走完了**:你知道了为什么架构判断越来越值钱(01),有了一套想清楚系统的框架(02),也学会了把想法画出来、讲明白(03)。 > > 但你可能会问:**每次都从零开始想吗?前人遇到的那些经典难题,有没有现成的「招式」可以套用?** > > 有。接下来的**第二段「掌握工具箱」**,就是来给你发牌的——架构师手里那些反复被验证过的「模式」,每一个都是对某一类问题的标准答案。 > > 👉 继续阅读:[04 · 十大核心架构模式](04-十大核心架构模式.md)