Arch Day 22: C4模型代码化 — 从画图工具到架构即代码
C4模型是Simon Brown提出的四层递进式架构可视化方法(Context → Container → Component → Code),而C4代码化则是用Structurizr DSL等文本语言定义架构模型,使其可版本控制、可自动生成、可CI/CD集成——从"手动画图"升级为"架构即代码"。
日期: 2026-04-21 (Day 22) 阶段: 第一阶段 - 架构基础 标签: #C4Model #StructurizrDSL #ArchitectureAsCode #DiagramAsCode #CI/CD
核心概念
一句话定义
C4模型是Simon Brown提出的四层递进式架构可视化方法(Context → Container → Component → Code),而C4代码化则是用Structurizr DSL等文本语言定义架构模型,使其可版本控制、可自动生成、可CI/CD集成——从"手动画图"升级为"架构即代码"。
为什么资深架构师仍需关注
| 痛点 | 资深架构师的真实场景 |
|---|---|
| 架构图漂移 | 你画的Visio/Draw.io图在3个月后已经和代码严重脱节,新人照着图理解系统,踩坑无数 |
| 多层视图不一致 | Context图说有5个外部系统,Container图里只画了3个,Component图又冒出来2个没见过的服务 |
| 评审效率低 | 架构评审时,大家对着一张截图讨论,无法diff、无法追溯变更历史 |
| 团队协作困难 | 多人同时改架构图导致冲突,二进制文件无法merge |
| 跨团队沟通成本 | 给CTO讲Context够了,给开发讲要到Component,每次手动调整抽象层级 |
作为10年金融软件经验的架构师,你一定经历过"那张架构图是谁画的?什么时候画的?现在还准吗?"的灵魂拷问。C4代码化就是这个问题的终极解法。
常见误区与反模式
| 误区 | 真相 |
|---|---|
| "C4就是画4层图" | C4是一种思维模型,四层只是最基础的静态视图,还需要动态视图、部署视图、系统景观图等 |
| "Code层要画每个类" | Code层在实践中几乎不手动维护,应该从代码自动生成(IDE类图/PlantUML等) |
| "Structurizr DSL等于C4" | DSL是工具,C4是方法论。你也可以用PlantUML-C4、Mermaid-C4、D2等工具实现C4 |
| "图画完就行了" | 没有集成到CI/CD的架构图 = 技术债。图必须可验证、可自动化 |
| "C4能替代所有架构图" | C4不擅长表达数据流、状态机、时序交互,需要补充其他图 |
知识点详解
知识点1:C4四层深度解析
C4的精髓在于逐层缩放(zoom in),每层服务于不同受众:
Level 1: System Context
├── 受众:所有人(包括非技术stakeholder)
├── 回答:系统在整个生态中的位置是什么?
├── 元素:系统(Software System) + 人(Person) + 外部系统
└── 典型错误:画了内部细节、包含了技术术语
Level 2: Container
├── 受众:技术决策者、架构师、Tech Lead
├── 回答:系统由哪些高层技术构建块组成?
├── 元素:Web App / API / Database / Message Queue / ...
└── 典型错误:把微服务的每个endpoint都画出来
Level 3: Component
├── 受众:开发团队
├── 回答:每个Container内部的主要组件和它们的职责?
├── 元素:Controller / Service / Repository / ...
└── 典型错误:和代码1:1映射,粒度太细
Level 4: Code
├── 受众:开发者(通常自动生成)
├── 回答:组件内部的类/接口结构?
├── 元素:Class / Interface / ...
└── 典型错误:手动维护,和代码脱节
高级用法:补充视图
| 视图类型 | 用途 | 何时需要 |
|---|---|---|
| System Landscape | 展示组织内所有系统及关系 | 企业架构全景、IT资产盘点 |
| Dynamic View | 展示运行时交互序列 | 关键业务流程、故障排查路径 |
| Deployment View | 展示物理/云部署拓扑 | DevOps规划、灾备方案、合规审查 |
| Filtered View | 从已有视图中筛选特定元素 | 面向特定受众裁剪视图 |
知识点2:Structurizr DSL语法精要
Structurizr DSL是C4代码化的事实标准。核心语法结构:
workspace "Digital Bank" "数字银行系统架构" {
!identifiers hierarchical
model {
// === 人物 ===
customer = person "零售客户" "使用手机银行的个人用户" {
tags "External"
}
backOfficeStaff = person "后台运营" "负责审批、风控、客服" {
tags "Internal"
}
// === 外部系统 ===
corebanking = softwareSystem "核心银行系统" "存量核心账务系统(大机)" {
tags "Existing"
}
pboc = softwareSystem "人民银行征信" "央行征信查询接口" {
tags "External"
}
unionpay = softwareSystem "银联" "跨行支付清算网络" {
tags "External"
}
// === 主系统 ===
digitalBank = softwareSystem "数字银行平台" "面向零售客户的全渠道数字银行" {
// --- Container层 ---
mobileApp = container "手机银行App" "iOS/Android客户端" "React Native" {
tags "Mobile"
}
webApp = container "网上银行" "Web端银行服务" "React + Next.js" {
tags "Web"
}
apiGateway = container "API网关" "统一入口、鉴权、限流、路由" "Kong / Spring Cloud Gateway" {
tags "Infrastructure"
}
accountService = container "账户服务" "开户、销户、账户查询" "Java Spring Boot" {
// --- Component层 ---
accountController = component "Account Controller" "REST API入口" "Spring MVC"
accountService_comp = component "Account Service" "业务逻辑层" "Spring Service"
accountRepository = component "Account Repository" "数据访问层" "Spring Data JPA"
kycValidator = component "KYC Validator" "身份验证组件" "Custom"
}
paymentService = container "支付服务" "转账、代扣、跨行支付" "Java Spring Boot"
loanService = container "贷款服务" "贷款申请、审批、放款、还款" "Java Spring Boot"
riskEngine = container "风控引擎" "实时风控评分、反欺诈" "Python + ML Models"
notificationService = container "通知服务" "短信、推送、站内信" "Go"
accountDB = container "账户数据库" "账户主数据" "PostgreSQL" {
tags "Database"
}
loanDB = container "贷款数据库" "贷款申请与合同数据" "PostgreSQL" {
tags "Database"
}
eventBus = container "事件总线" "异步事件驱动" "Apache Kafka" {
tags "MessageQueue"
}
cache = container "缓存层" "热数据缓存" "Redis Cluster" {
tags "Cache"
}
}
// === 关系 ===
customer -> digitalBank.mobileApp "使用" "HTTPS"
customer -> digitalBank.webApp "使用" "HTTPS"
backOfficeStaff -> digitalBank.webApp "管理操作" "HTTPS"
digitalBank.mobileApp -> digitalBank.apiGateway "API调用" "HTTPS/JSON"
digitalBank.webApp -> digitalBank.apiGateway "API调用" "HTTPS/JSON"
digitalBank.apiGateway -> digitalBank.accountService "路由" "gRPC"
digitalBank.apiGateway -> digitalBank.paymentService "路由" "gRPC"
digitalBank.apiGateway -> digitalBank.loanService "路由" "gRPC"
digitalBank.accountService -> digitalBank.accountDB "读写" "JDBC"
digitalBank.accountService -> digitalBank.cache "缓存" "Redis Protocol"
digitalBank.accountService -> corebanking "同步账务" "MQ/ESB"
digitalBank.paymentService -> unionpay "跨行清算" "ISO 8583"
digitalBank.paymentService -> digitalBank.eventBus "发布事件" "Kafka Protocol"
digitalBank.loanService -> digitalBank.loanDB "读写" "JDBC"
digitalBank.loanService -> digitalBank.riskEngine "风控评分" "gRPC"
digitalBank.loanService -> pboc "征信查询" "HTTPS"
digitalBank.riskEngine -> digitalBank.eventBus "消费事件" "Kafka Protocol"
digitalBank.notificationService -> digitalBank.eventBus "消费事件" "Kafka Protocol"
// Component层关系
digitalBank.accountService.accountController -> digitalBank.accountService.accountService_comp "调用"
digitalBank.accountService.accountService_comp -> digitalBank.accountService.accountRepository "调用"
digitalBank.accountService.accountService_comp -> digitalBank.accountService.kycValidator "调用"
}
views {
// === System Context ===
systemContext digitalBank "SystemContext" {
include *
autoLayout
description "数字银行系统上下文图"
}
// === Container ===
container digitalBank "Containers" {
include *
autoLayout
description "数字银行容器图"
}
// === Component (Account Service) ===
component digitalBank.accountService "AccountComponents" {
include *
autoLayout
description "账户服务组件图"
}
// === Dynamic View: 贷款申请流程 ===
dynamic digitalBank "LoanApplication" "贷款申请流程" {
customer -> digitalBank.mobileApp "提交贷款申请"
digitalBank.mobileApp -> digitalBank.apiGateway "转发请求"
digitalBank.apiGateway -> digitalBank.loanService "路由到贷款服务"
digitalBank.loanService -> pboc "查询征信"
digitalBank.loanService -> digitalBank.riskEngine "请求风控评分"
digitalBank.riskEngine -> digitalBank.loanService "返回风控结果"
digitalBank.loanService -> digitalBank.loanDB "保存申请记录"
digitalBank.loanService -> digitalBank.eventBus "发布审批事件"
digitalBank.notificationService -> digitalBank.eventBus "消费通知事件"
autoLayout
}
// === Deployment View ===
deployment digitalBank "Production" "ProductionDeployment" {
deploymentNode "阿里云 VPC" {
deploymentNode "可用区A" {
deploymentNode "Kubernetes Cluster" {
deploymentNode "App Namespace" {
containerInstance digitalBank.apiGateway
containerInstance digitalBank.accountService
containerInstance digitalBank.paymentService
containerInstance digitalBank.loanService
}
deploymentNode "ML Namespace" {
containerInstance digitalBank.riskEngine
}
}
}
deploymentNode "RDS" {
containerInstance digitalBank.accountDB
containerInstance digitalBank.loanDB
}
deploymentNode "中间件" {
containerInstance digitalBank.eventBus
containerInstance digitalBank.cache
}
}
autoLayout
}
// === 样式 ===
styles {
element "Software System" {
background "#1168bd"
color "#ffffff"
}
element "Person" {
shape "Person"
background "#08427b"
color "#ffffff"
}
element "Container" {
background "#438dd5"
color "#ffffff"
}
element "Component" {
background "#85bbf0"
color "#000000"
}
element "Database" {
shape "Cylinder"
}
element "MessageQueue" {
shape "Pipe"
}
element "External" {
background "#999999"
}
element "Existing" {
background "#999999"
color "#ffffff"
}
element "Mobile" {
shape "MobileDeviceLandscape"
}
element "Web" {
shape "WebBrowser"
}
}
}
}
知识点3:CI/CD集成方案
架构图代码化的终极价值在于持续验证:
# .github/workflows/architecture.yml
name: Architecture Validation
on:
push:
paths:
- 'docs/architecture/**'
- 'structurizr/**'
pull_request:
paths:
- 'docs/architecture/**'
jobs:
validate-and-render:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# 1. 语法验证
- name: Validate Structurizr DSL
run: |
docker run --rm -v $(pwd)/structurizr:/workspace \
structurizr/cli validate \
-workspace /workspace/workspace.dsl
# 2. 自动渲染图片
- name: Export diagrams
run: |
docker run --rm -v $(pwd)/structurizr:/workspace \
-v $(pwd)/docs/images:/output \
structurizr/cli export \
-workspace /workspace/workspace.dsl \
-format plantuml \
-output /output
# 3. 生成PNG
- name: Render PlantUML to PNG
run: |
docker run --rm -v $(pwd)/docs/images:/data \
plantuml/plantuml -tpng /data/*.puml
# 4. 提交更新的图片
- name: Commit rendered diagrams
run: |
git add docs/images/*.png
git commit -m "chore: auto-update architecture diagrams" || true
git push
# 5. 架构合规检查(可选)
- name: Check architecture constraints
run: |
# 例如:验证所有外部系统都有标签
python scripts/validate_architecture.py
Structurizr CLI本地工作流
# 安装
brew install structurizr-cli # macOS
# 或 Docker
docker pull structurizr/cli
# 验证DSL语法
structurizr-cli validate -workspace workspace.dsl
# 导出为PlantUML
structurizr-cli export -workspace workspace.dsl -format plantuml
# 导出为Mermaid
structurizr-cli export -workspace workspace.dsl -format mermaid
# 启动本地预览服务器
structurizr-cli serve -workspace workspace.dsl -port 8080
# 推送到Structurizr Cloud
structurizr-cli push -workspace workspace.dsl \
-id YOUR_WORKSPACE_ID \
-key YOUR_API_KEY \
-secret YOUR_API_SECRET
知识点4:C4的局限性与补充策略
C4不是银弹。在金融系统中,你经常需要补充以下视图:
| 场景 | C4能力 | 需要补充 | 推荐工具 |
|---|---|---|---|
| 复杂业务流程 | Dynamic View(简单序列) | BPMN流程图 | Camunda Modeler |
| 数据流向与合规 | 关系箭头(粗粒度) | 数据流图(DFD) + 数据分类标签 | 自定义 |
| 状态机 | 不支持 | 状态图 | PlantUML State |
| API契约 | Container间关系 | OpenAPI Spec + AsyncAPI | Swagger/Redoc |
| 网络拓扑 | Deployment View | 详细网络分区图 | Draw.io/Diagrams.net |
| 灾备方案 | 多Deployment View | RTO/RPO标注的灾备切换图 | 自定义 |
| 数据模型 | 不支持 | ER图 | dbdiagram.io |
金融系统的最佳实践:C4作为"主干",按需挂载补充视图:
C4 System Context
├── C4 Container → 补充:数据流图(合规用)
│ ├── C4 Component → 补充:序列图(关键流程)
│ └── C4 Component → 补充:状态机(订单/贷款)
├── C4 Deployment → 补充:网络拓扑(安全审计)
├── C4 Dynamic → 补充:BPMN(业务流程)
└── 补充:ER图(数据模型)
对比分析
C4 vs 4+1 View Model vs arc42
| 维度 | C4 Model | 4+1 View Model | arc42 |
|---|---|---|---|
| 提出者 | Simon Brown (2018) | Philippe Kruchten (1995) | Gernot Starke |
| 核心思想 | 逐层缩放 | 5个并行视图 | 12章模板 |
| 视图数量 | 4层+补充视图 | 5个(逻辑/开发/进程/物理/场景) | 12个章节 |
| 学习曲线 | ★★☆ 低 | ★★★ 中 | ★★★★ 中高 |
| 代码化支持 | ★★★★★ (Structurizr DSL) | ★★☆ (无专用工具) | ★★★ (Markdown模板) |
| 自动化支持 | CI/CD集成成熟 | 需自建 | Docs-as-Code可集成 |
| 适用规模 | 单系统~中等 | 大型系统 | 任意规模 |
| 与UML关系 | 刻意简化 | 基于UML | 不限定 |
| 受众适配 | 不同层级→不同受众 | 不同视图→不同关注点 | 全面但需裁剪 |
| 金融行业适用度 | ★★★★ | ★★★ | ★★★★★ |
| 团队采纳难度 | 低(开发者友好) | 高(需UML基础) | 中(文档量大) |
资深架构师的选择策略:
- 小团队/创业公司:C4足够,轻量高效
- 中型金融系统:C4 + arc42文档模板(C4画图,arc42组织文档)
- 大型企业架构:ArchiMate(企业级) + C4(系统级) + arc42(文档)
Diagram-as-Code工具对比
| 工具 | 语言 | C4支持 | 优势 | 劣势 |
|---|---|---|---|---|
| Structurizr DSL | 专用DSL | 原生 | C4原生、模型驱动、多视图 | 生态较小 |
| PlantUML-C4 | PlantUML扩展 | 库 | 生态成熟、CI友好 | 布局控制弱 |
| Mermaid-C4 | Mermaid扩展 | 库 | GitHub/GitLab原生渲染 | 功能简陋 |
| D2 | D2 | 可模拟 | 布局美观、语法简洁 | C4非原生 |
| Diagrams(Python) | Python | 可模拟 | 云架构图强、可编程 | 非C4专用 |
架构设计实操
设计目标
为"数字银行"系统创建完整的C4代码化方案,包含:
- 4层静态视图
- 1个动态视图(贷款申请流程)
- 1个部署视图(生产环境)
- CI/CD自动渲染管线
方案设计
目录结构:
project-root/
├── architecture/
│ ├── workspace.dsl # Structurizr主文件
│ ├── model/
│ │ ├── people.dsl # 人物定义(大型项目拆分)
│ │ ├── systems.dsl # 系统定义
│ │ └── relationships.dsl # 关系定义
│ ├── views/
│ │ ├── context.dsl # Context视图
│ │ ├── containers.dsl # Container视图
│ │ ├── components.dsl # Component视图
│ │ ├── dynamic.dsl # 动态视图
│ │ └── deployment.dsl # 部署视图
│ └── styles.dsl # 全局样式
├── docs/
│ ├── architecture/
│ │ ├── images/ # 自动生成的图片
│ │ └── decisions/ # ADR目录
│ └── arc42/ # arc42文档
├── .github/
│ └── workflows/
│ └── architecture.yml # CI/CD管线
└── scripts/
└── validate_architecture.py # 自定义验证脚本
ADR: 选择C4 + Structurizr DSL作为架构可视化方案
# ADR-022: 架构可视化方案选型
## 状态
已接受
## 背景
当前架构图散落在Confluence、PPT、Draw.io中,存在以下问题:
1. 无版本控制,无法追溯变更
2. 多人协作时图片冲突
3. 不同层级视图不一致
4. 新人入职无法快速理解系统全貌
## 决策
采用C4模型 + Structurizr DSL作为主要架构可视化方案:
- Structurizr DSL定义模型(单一数据源)
- CI/CD自动渲染为PNG/SVG
- 补充视图用PlantUML(序列图、状态图)
- 文档用arc42模板组织
## 理由
1. **模型驱动**:DSL定义一次,自动生成多层视图,保证一致性
2. **Git友好**:文本文件可diff/merge/review
3. **低学习成本**:开发者5分钟上手DSL语法
4. **CI集成**:PR自动验证语法+渲染图片
5. **团队采纳率预期高**:比UML/ArchiMate门槛低得多
## 风险
- Structurizr DSL社区较小,长期维护存疑 → 可随时导出为PlantUML迁移
- 复杂布局控制有限 → 接受自动布局,放弃像素级控制
- Code层不实用 → 不维护Code层,用IDE自动生成
## 后果
- 所有架构变更必须先更新DSL文件
- PR模板增加"是否需要更新架构图"检查项
- 每季度review架构图与实际系统的偏差
权衡分析
| 权衡 | 选择 | 理由 |
|---|---|---|
| 手动精调布局 vs 自动布局 | 自动布局 | 维护成本远低于手动,接受"不完美"的布局 |
| 单一DSL文件 vs 拆分多文件 | 中型项目单文件,大型项目拆分 | 避免过早引入复杂度 |
| Structurizr Cloud vs 自托管 | 自托管(Docker) | 金融合规要求,架构图不外传 |
| 每次PR渲染 vs 定期渲染 | 每次PR渲染 | 保证架构图始终最新 |
AI增强实践
AI辅助架构图生成
Prompt: 我有一个数字银行系统,包含以下服务:
- 手机银行App (React Native)
- API网关 (Kong)
- 账户服务、支付服务、贷款服务 (Spring Boot)
- 风控引擎 (Python ML)
- PostgreSQL、Kafka、Redis
外部系统:核心银行(大机)、央行征信、银联
请用Structurizr DSL生成完整的C4模型,包含Context、Container、
一个核心Component、一个Dynamic View和Production Deployment View。
AI辅助架构审查
Prompt: 请审查以下Structurizr DSL代码,检查:
1. 是否有孤立节点(无关系的元素)
2. 是否有缺失的数据流方向
3. 命名是否一致(技术术语 vs 业务术语混用)
4. 是否遗漏了关键的非功能性关注点(安全、监控、日志)
5. 作为金融系统,是否遗漏了合规相关的组件(审计日志、数据加密)
AI自动生成架构变更描述
# 在CI中自动生成DSL变更的自然语言描述
# 用于PR review和架构变更周报
def generate_change_description(diff_text):
prompt = f"""
以下是Structurizr DSL的git diff,请用中文描述架构变更:
1. 新增了什么?
2. 修改了什么?
3. 删除了什么?
4. 这些变更的潜在影响是什么?
Diff:
{diff_text}
"""
return call_llm(prompt)
与Web3/DeFi的关联
DeFi协议的C4建模
DeFi系统天然适合C4建模,因为它的边界清晰:
Context层:
├── Person: 零售用户、LP提供者、治理参与者、套利机器人
├── Software System: DEX协议
├── External: 预言机(Chainlink)、Layer2桥、其他DeFi协议
└── 特殊:智能合约既是Container也是External的边界模糊
Container层:
├── Frontend DApp (React)
├── Subgraph (The Graph indexer)
├── Smart Contracts (Solidity)
│ ├── Router Contract
│ ├── Factory Contract
│ ├── Pool Contracts
│ └── Governance Contract
├── Keeper/Bot Infrastructure
└── IPFS (治理提案存储)
挑战:
1. 智能合约之间的关系是链上调用,和传统API调用不同
2. 用户可以绕过Frontend直接调合约
3. MEV/套利机器人是"非预期"的参与者
4. 合约一旦部署不可变,架构演进通过代理模式实现
Web3项目的C4最佳实践
| 传统系统 | Web3系统 | C4建模差异 |
|---|---|---|
| Server拥有数据 | 链上数据公开 | Container边界需包含链上状态 |
| API网关统一入口 | 用户可直连合约 | 需画出"直连路径" |
| 数据库可修改 | 链上不可变 | 部署视图需体现不可变性 |
| 单一信任域 | 去信任 | 信任边界是关键标注 |
今日思考
思考题1:模型驱动 vs 图驱动
C4代码化的核心价值是"模型驱动"——你定义的是模型而非图,图只是模型的一个渲染视图。这和传统画图方式有什么本质区别?在你的金融系统经验中,有没有因为"只有图没有模型"而导致的问题?
思考题2:架构图的保鲜期
在你过去10年的经验中,一张架构图从绘制到过时通常需要多久?CI/CD集成能把这个"保鲜期"延长多少?有没有CI/CD也解决不了的"图码不一致"问题?
思考题3:C4在微服务+事件驱动架构中的挑战
当系统有50+微服务和复杂的Kafka事件流时,Container图会变得极其复杂。你会如何处理?分域画多张Container图?还是引入新的抽象层?
面试题准备
面试题1:为什么选C4而不是UML?
30秒版本: C4提供了恰到好处的抽象层级,四层缩放自然对应不同受众。相比UML,C4学习成本低一个数量级,开发团队实际采纳率远高于UML。最关键的是C4有Structurizr DSL支持代码化,可以纳入CI/CD自动验证。
2分钟版本: UML的问题不是它不够强大,而是它太强大了。13种图类型、几十种符号,大部分开发者记不住也不愿学。在我过去的金融项目中,UML图往往只有架构师自己看,开发团队直接忽略——这失去了架构图的核心价值。
C4的设计哲学是"just enough":
- 四层对应四种受众:Context给所有人看,Container给技术决策者,Component给开发团队,Code自动生成
- 只有4种元素:Person、Software System、Container、Component——没有心智负担
- 代码化支持成熟:Structurizr DSL → Git → CI/CD → 自动渲染
- 模型驱动:定义一个模型,渲染多个视图,保证一致性
当然C4也有局限:它不擅长序列图、状态机、数据模型。我的实践是C4作为"主干",需要时用PlantUML补充序列图和状态图。
追问准备:
Q: 那什么时候你还是会用UML? A: 三个场景:1) 复杂的状态机(如贷款生命周期),用UML State Diagram;2) 跨系统的复杂时序交互,用Sequence Diagram;3) 对接传统企业客户时,他们的架构治理流程要求UML。
Q: Structurizr DSL和PlantUML怎么选? A: 如果只画C4图,Structurizr DSL更好(模型驱动,一次定义多视图)。如果需要混合C4 + 序列图 + 状态图,PlantUML更灵活。我通常两者配合使用。
面试题2:架构图如何保持和代码同步?
30秒版本: 三个层面:1) 代码化(Structurizr DSL存在Git里);2) CI/CD自动验证和渲染;3) 流程约束(PR模板包含"是否更新架构图"检查项)。终极方案是Architecture Fitness Functions——用ArchUnit等工具自动验证代码是否符合架构图的约束。
2分钟版本: 架构图和代码脱节是行业普遍痛点。我的实践分四个层次逐步推进:
Level 1: 文本化 把图从Visio/PPT迁移到文本DSL(Structurizr/PlantUML),存入Git。这一步就能享受版本控制、diff、code review。
Level 2: 自动化渲染 CI/CD管线自动验证DSL语法、渲染图片、提交到文档目录。团队看到的永远是最新渲染的图。
Level 3: 流程约束 PR模板增加checklist:"本次变更是否涉及服务边界/接口变更?如果是,请同步更新architecture/workspace.dsl"。Code review时架构师检查。
Level 4: 自动化验证(Fitness Functions) 用ArchUnit等工具定义架构规则(如"Controller只能调用Service,不能直接调Repository"),在CI中自动检查。代码违反架构约束时构建失败。
这四个层面的成本和价值逐层递增,建议按顺序推进而非一步到位。
学习资源
| 资源 | 类型 | 推荐度 |
|---|---|---|
| c4model.com | Simon Brown官网 | ★★★★★ 必读 |
| Structurizr DSL文档 | 官方文档 | ★★★★★ 实操必备 |
| Structurizr DSL Cookbook | 实战cookbook | ★★★★ |
| Simon Brown "Software Architecture for Developers" | 书 | ★★★★ |
| Diagrams as Code 2.0 | Simon Brown演讲 | ★★★★ |
| PlantUML-C4 | 开源库 | ★★★ 备选方案 |
明日预告
Day 23: ArchiMate企业级建模 — 从系统级架构上升到企业级架构。C4擅长"一个系统多层视图",而ArchiMate擅长"多个系统一个全景"。我们将学习ArchiMate的三层+动机+迁移视图,并实操画银行贷款系统的企业架构全栈图。当你需要和企业架构委员会、CTO Office沟通时,ArchiMate是比C4更适合的语言。