文章摘要
C4模型是一种分层级的软件架构描述方法,包含Context(环境)、Container(容器)、Component(组件)和Code(代码)四个层次。它像一台变焦相机,从宏观到微观逐步聚焦系统结构:Context展示系统与外部世界的关系,Container划分主要系统模块,Component细化内部功能组件,Code呈现具体代码实现。该模型通过城市比喻(全球→城区→建筑→房间)形象说明各层关系,典型应用如在线商城系统的架构设计。其核心价值在于分层清晰、沟通高效,让不同角色都能在适合的抽象层级理解系统,同时便于文档维护和变更管理。
一、C4模型是什么?
C4模型的名字来自它的四个层次:
- Context(环境/上下文)
- Container(容器)
- Component(组件)
- Code(代码)
它像一台“变焦相机”,可以从远到近、从宏观到微观,逐步聚焦你的系统结构。
二、形象比喻
想象你要介绍一座“城市”
1. Context(城市在世界的位置)
- 你先告诉别人:这座城市在中国东部,靠近海边,和周围有哪些城市相连。
- 这就是“环境图”:你的系统和外部世界的关系。
2. Container(城市里的区块)
- 你再说:这座城市有商业区、住宅区、工业区、公园等。
- 这就是“容器图”:你的系统由哪些主要部分组成,每个部分负责什么。
3. Component(区块里的建筑)
- 你进一步介绍:商业区里有商场、写字楼、餐厅、电影院……
- 这就是“组件图”:每个容器内部有哪些功能模块,它们怎么协作。
4. Code(建筑的房间布局)
- 最后你带人走进商场,看每一层、每个店铺、每个房间的具体布局。
- 这就是“代码图”:具体到类、方法、文件的实现细节。
三、每一层的作用和典型问题
层级 | 关注点 | 典型问题举例 |
---|---|---|
Context | 系统与外部世界的关系 | 谁会用这个系统?和哪些外部系统交互? |
Container | 系统的主要运行单元 | 有哪些服务/应用?怎么部署? |
Component | 容器内部的功能模块 | 这个服务内部怎么分工?模块如何协作? |
Code | 具体实现(类、方法、文件) | 这个模块的代码结构如何? |
四、举个实际例子:在线商城系统
1. Context(环境图)
[用户] ←→ [在线商城系统] ←→ [支付平台]
←→ [物流系统]
- 说明:商城系统和用户、支付、物流等外部系统的关系。
2. Container(容器图)
[Web前端] [移动App] [订单服务] [商品服务] [用户服务] [数据库]
- 说明:商城系统由哪些主要应用/服务组成,每个服务的职责是什么。
3. Component(组件图)——以订单服务为例
[订单服务]
├─ 订单控制器(OrderController)
├─ 订单管理器(OrderManager)
├─ 支付集成(PaymentIntegration)
├─ 订单仓储(OrderRepository)
- 说明:订单服务内部有哪些模块,各自负责什么。
4. Code(代码图)
OrderManager.java
├─ createOrder()
├─ cancelOrder()
├─ getOrderStatus()
- 说明:具体到类、方法、文件的实现。
五、C4模型的价值
- 沟通无障碍:不同角色能在自己关心的层次上理解系统。
- 分层清晰:从宏观到微观,逐步细化,避免一上来就陷入细节。
- 文档易维护:每层只关注该层的内容,变更容易同步。
六、总结口诀
C4模型像变焦镜头,先看全景(Context),再看分区(Container),再看楼层(Component),最后进房间(Code)。
下面我会用射击游戏为例,给你展示一套完整的C4四层图示例,并讲讲怎么画C4图。
(注:C4图可以用手绘、Visio、draw.io、PlantUML等工具画,重点是层次清晰、关系明确。)
一、射击游戏的C4四层图示例
1. Context(环境/上下文图)
目的:展示射击游戏与外部世界的关系。
+-------------------+ +-------------------+
| 玩家 | <-----> | 射击游戏系统 | <-----> [游戏服务器]
+-------------------+ +-------------------+ |
| |
v v
[第三方登录平台] [排行榜/成就系统]
- 玩家通过PC/主机/手机访问射击游戏。
- 游戏系统与服务器、第三方平台、排行榜等外部系统交互。
2. Container(容器图)
目的:展示射击游戏的主要运行单元(应用/服务/数据库等)。
+-------------------+ +-------------------+ +-------------------+
| 客户端(Unity) |<---->| 游戏服务器 |<---->| 数据库 |
+-------------------+ +-------------------+ +-------------------+
| | |
v v v
[UI模块][渲染][输入][网络] [房间管理][物理][AI][同步] [玩家数据][战绩][配置]
- 客户端负责渲染、输入、UI、网络通信。
- 服务器负责房间管理、物理判定、AI、同步。
- 数据库存储玩家数据、战绩、配置等。
3. Component(组件图)
目的:展示容器内部的主要功能模块及其关系。
以“游戏服务器”为例:
+------------------- 游戏服务器 -------------------+
| |
| +-------------------+ +-------------------+ |
| | 房间管理组件 | | 物理碰撞组件 | |
| +-------------------+ +-------------------+ |
| | AI组件 | | 网络同步组件 | |
| +-------------------+ +-------------------+ |
| | 武器系统组件 | | 玩家管理组件 | |
| +-------------------+ +-------------------+ |
| |
+--------------------------------------------------+
- 房间管理:创建/销毁房间,分配玩家。
- 物理碰撞:判定子弹、角色、环境的碰撞。
- AI:敌人行为、巡逻、攻击。
- 网络同步:同步玩家状态、广播事件。
- 武器系统:武器切换、射击、弹药管理。
- 玩家管理:玩家状态、分数、复活等。
4. Code(代码/类图)
目的:展示某个组件的具体代码结构。
以“武器系统组件”为例:
WeaponSystem
├─ WeaponManager
│ ├─ equipWeapon()
│ ├─ switchWeapon()
├─ Weapon
│ ├─ fire()
│ ├─ reload()
│ ├─ getAmmoCount()
├─ Bullet
│ ├─ move()
│ ├─ checkCollision()
├─ RecoilController
│ ├─ applyRecoil()
- WeaponManager:管理武器切换、装备。
- Weapon:武器基类,包含射击、换弹等方法。
- Bullet:子弹对象,负责移动和碰撞检测。
- RecoilController:后坐力控制。
二、怎么画C4图?
- 确定层级:先画Context,再画Container,再画Component,最后画Code。
- 每层只关注本层内容:不要在Context图里画类,也不要在Code图里画外部系统。
- 用简单的方框+箭头:方框代表系统/容器/组件/类,箭头代表关系或调用。
- 加简短说明:每个方框下写一句话,说明它的作用。
- 工具推荐:
- 纸和笔(头脑风暴)
- draw.io(免费在线)
- PlantUML(可写代码生成C4图,适合开发者)
- Visio、ProcessOn等
三、总结
- C4模型让你从宏观到微观,逐步拆解射击游戏的架构。
- 画C4图时,层次分明、关系清晰、说明简洁最重要。
- 你可以用C4模型和团队、老板、合作方高效沟通复杂系统。