让文档跟着代码走
文档总是过时的
文档会腐烂。
不是因为团队懒惰。是因为熵增是自然规律。代码每天在变,文档需要人工同步。这个过程消耗能量,需要纪律,依赖记忆。任何一个环节松懈,文档就开始偏离真相。
大多数团队的应对方式是"加强文档审查"、"建立文档规范"、"定期更新文档"。这些方法试图用更多的纪律对抗熵增。
但纪律是最稀缺的资源。
真正有效的方法不是更频繁的手工维护,而是减少需要手工维护的文档数量。让文档"活"起来——跟随代码自动更新,而不是依赖人的记忆。
文档的三种生命形态
文档不是单一类型。它有三种形态,每种形态有不同的生命周期。
第一种:活文档。 它就是代码本身。函数签名、类型定义、代码注释。这些文档随代码一起编辑、一起提交、一起审查。它们永远不会过时,因为它们就是真相。
第二种:半自动文档。 它从代码生成,但需要模板和规则。API参考、数据库Schema、组件清单。这些文档由工具扫描代码自动生成。人定义生成规则,机器执行更新。
第三种:手工文档。 架构设计、部署流程、开发指南。这些文档无法从代码推导,必须由人编写。它们更新最慢,也最容易腐烂。
这不是武断的分类。它基于一个简单的原则:文档离代码越近,越不容易过时。
活文档嵌入代码中,零距离。半自动文档通过工具连接代码,距离可控。手工文档依赖人工同步,距离最远。
减少文档腐烂的方法就是尽可能多地使用前两种,尽可能少地依赖第三种。
💡 Click the maximize icon to view in fullscreen
活文档:代码即文档
最好的文档就是代码本身。
/**
* 计算用户的积分消耗成本
*
* @param credits - 用户消耗的积分数量
* @param vendorCost - 厂商API的实际成本(美元)
* @returns 利润率百分比
*/
function calculateProfitMargin(credits: number, vendorCost: number): number {
const revenue = credits * 0.0483 // Pro方案单积分价值
return (revenue - vendorCost) / revenue
}
这段代码的文档不会过时。因为函数签名、参数类型、返回值都是编译器验证的。注释紧挨着代码,修改代码时很难忽略注释。
这种文档的维护成本最低。开发者不需要额外的步骤,不需要切换到另一个文件,不需要记得"别忘了更新文档"。文档就在眼前。
但活文档有局限。它只能描述单个函数或类的行为,无法展示系统的全貌。这时需要第二层。
半自动文档:让机器做记忆的工作
当系统有50个API时,没人能记住每个API的参数和返回值。这时需要API参考文档。
但手工维护API参考是灾难。每次接口变更,都要记得更新两个地方:代码和文档。人的记忆不可靠。
解决方法是让机器扫描代码,自动生成文档。
# 代码提交时自动触发
git commit → pre-commit hook → 扫描代码 → 生成文档 → 提交文档
开发者只需要写好代码注释(活文档),工具自动汇总成API参考(半自动文档)。维护的负担减少了一半。
文档生成不应该是手动命令。它应该绑定在开发流程的关键节点:
- 提交前:pre-commit hook生成文档,确保文档和代码一起提交
- 构建时:CI流程生成文档,确保文档和部署同步
- 发布后:自动部署文档站点,确保用户看到的是最新版本
自动化的关键是"让它成为流程的一部分,而不是额外的任务"。
在Purikura项目中,我们用TypeDoc从TypeScript代码生成API文档,用脚本从数据库Schema生成表结构文档。这些文档每次提交时自动更新,开发者无需手工维护。
手工文档:不得不做的事
有些文档无法自动生成。
架构设计解释"为什么这样设计"。部署流程记录"在什么环境做什么操作"。这些知识无法从代码推导。
手工文档是必需的,但应该被最小化。
原则一:只写无法自动化的内容。 如果某个信息可以从代码生成,就不要手工编写。比如API参数列表属于半自动文档,不应该出现在架构设计文档中。
原则二:用图表代替大段文字。 一张流程图胜过一千字描述。Mermaid图表嵌入在Markdown中,修改方便,版本控制友好。就像API文档标准中的成本计算流程图。
原则三:在重大变更时强制更新。 架构变更、部署流程变更、API设计变更——这些事件必须触发文档更新。不是靠自觉,是靠流程约束。
💡 Click the maximize icon to view in fullscreen
为什么自动化优先
有人会说:"写文档也没那么费时间,手工维护就好。"
问题不在时间,在可靠性。
人会忘记。人会疲倦。人会在deadline前选择跳过"非关键步骤"。文档更新就是这种"非关键步骤"——当它被跳过时,系统不会崩溃,测试不会失败,用户不会抱怨。
但文档会悄悄腐烂。三个月后,没人知道这个函数为什么这样设计。六个月后,新人看着代码和文档的差异,不知道该相信哪个。
自动化不是为了节省时间,是为了确保事情一定会发生。
就像防御式编程不是因为程序员水平差,而是承认人不可能记住所有边界条件。文档自动化不是因为团队懒,而是承认人的记忆不可靠。
自动化不是免费的。
建立文档生成流程需要时间。配置CI需要学习。编写生成脚本需要调试。这些前期成本是真实的。
但这是一次性投入。流程建立后,它会持续运转,不需要额外维护。而手工文档是持续成本,每次代码变更都要重复。
选择取决于时间尺度。如果项目只会存在三个月,手工文档可能更快。如果项目会持续一年以上,自动化是唯一可持续的选择。
文档是代码的镜像
文档不是附加物。它是系统的另一种表达。
代码描述"怎么做",文档描述"为什么做"和"如何使用"。两者应该同步演进,而不是代码在前、文档在后。
当文档落后于代码,说明流程有问题。要么文档分类错误(应该是活文档或半自动文档,却被当成手工文档维护),要么缺少自动化工具,要么团队对文档重要性认识不足。
让文档跟着代码走,不是加强纪律,是改变系统设计。把更多文档推向活文档和半自动文档,减少手工文档的依赖。让自动化成为流程的一部分,而不是额外的负担。
文档衰败是熵增的自然结果。但熵增可以被延缓,只要你理解文档的三种形态,并为每种形态选择正确的维护策略。
Related Posts
Articles you might also find interesting
文档标准是成本计算的前提
API文档不只是写给开发者看的。它定义了系统的边界、成本结构和可维护性。统一的文档标准让隐性成本变得可见。
定价界面优化的三层方法
数据诚实、决策引导、视觉精调——三层递进的优化方法。从移除虚假功能到帮助用户选择,再到像素级修复,每一步都在解决真实问题
用 AI Agents 加速测试环境配置
测试环境的配置是重复的琐事。环境变量、测试数据库、配置文件——这些步骤消耗时间但不产生直接价值。AI agents 改变了这个等式。
API 测试各种边界情况
边界情况是系统最脆弱的地方,也是最容易被忽略的地方。测试边界情况不是为了追求完美,而是为了理解系统的真实边界。
离屏渲染:照片捕获为什么需要独立的 canvas
实时流与静态合成的本质冲突,决定了系统必须分离。理解这种分离,就理解了架构设计中最重要的原则。
集中式配置:让 Reddit 组件脱离重复泥潭
当同一份数据散落在多个文件中,维护成本呈指数级增长。集中式配置不是技术选择,而是对抗熵增的必然手段。
CRUD 操作
四个字母背后,是数据的生命周期,是权限的边界,也是系统设计的基础逻辑
双重导出管道的架构选择
在用户生成内容场景中,速度与质量的权衡决定了导出架构。理解两种不同管道的设计逻辑,能够更准确地把握产品体验的边界。
端到端 Postback 模拟测试
真实的测试不是模拟完美的流程,而是重现真实世界的混乱。Postback 测试的价值在于发现系统在不确定性中的表现。
错误隔离
失败是必然的。真正的问题不是失败本身,而是失败如何蔓延。错误隔离不是为了消除失败,而是为了控制失败的范围。
Purikura的页面系统
通过五层分层继承复用架构,实现零代码修改的页面生成系统。从类型定义到页面渲染,每一层专注单一职责,实现真正的数据驱动开发。
重复数据的迁移实践:从 N 个文件到 1 个真相源
当同一份 Reddit posts 配置散落在多个文件中,维护成本以文件数量指数增长。迁移到集中式配置不是技术选择,而是对复杂度的清算。
Git Hooks 驱动的文档同步
文档不会自动更新,除非你让它自动更新。Git Hooks 是最接近代码变更的触发点,也是对抗文档腐烂最有效的位置。
在运行的系统上生长新功能
扩展不是推倒重来,而是理解边界,找到生长点。管理层作为观察者和调节器,附着在核心系统上,监测它,影响它,但不改变它的运行逻辑。
实现幂等性处理,忽略已处理的任务
在代码层面识别和忽略已处理的任务,不是简单的布尔检查,而是对时序、并发和状态的深刻理解
分层修复
生产问题没有银弹。P0 止血,P1 加固,P2 优化。优先级不是排序,而是在不确定性下的决策框架。
多厂商 AI 调度:统一混乱的供应商生态
当你依赖第三方 AI 服务时,单点故障是最大的风险。多厂商调度不只是技术架构,更是对不确定性的应对策略。
分布式 Workers 的解耦设计
通过微服务架构和队列系统,实现高可用的 AI 任务处理。从单体到分布式,每个设计决策都是对复杂度的权衡。
Studio 前端架构:从画布到组件的设计思考
深入 Purikura Studio 前端架构设计,探讨 DOM-based 画布、状态管理和组件化的实践经验
Studio 系统架构:从状态机到端到端流程
深入 Studio 系统的状态管理中心、组件协调机制和 AI 生成的完整数据流,理解前后端集成的设计逻辑
Context 驱动的认证状态管理
认证系统的核心不在登录按钮,而在状态同步。如何让整个应用感知用户状态变化,决定了用户体验的流畅度。
第三方回调的状态映射完整性
KIE.AI 视频生成的三个修复揭示了一个本质问题:回调不只是接收结果,是建立状态映射。没有 vendor_task_id,系统就失去了追溯能力。
统一积分系统的设计实践
从多套积分到单一积分池的架构演进,以及背后的原子性、一致性设计
幂等性检查
在不确定的系统中,幂等性检查是对重复的容忍,是对稳定性的追求,也是对失败的预期与接纳