告别文档恐惧症:轻松掌握技术文档写作技巧
告别文档恐惧症:轻松掌握技术文档写作技巧
dong4j为什么你不爱写技术文档?以及怎样才能写好技术文档?
我以前看过一个投票,盘点程序员不喜欢的事,有两条和文档相关:
不喜欢写文档;
不喜欢项目文档太少。
看起来很矛盾,却很现实。基本上大家都认同:“项目文档很重要”,然而我们在项目中总是短期高估文档的重要性,而长期低估文档的重要性。
结果就是口号喊的很响:要重视文档、要写好文档、要多写文档,然而随着项目的推进,总有比文档优先级更重要的任务,文档的优先级总是被有意无意推迟,导致项目的文档缺失、老旧、无人维护。
1.1 为什么不爱写文档?
那么为什么程序员都不爱写文档呢?我总结了一下大致有下面这些原因。
- 不知道怎么写
不知道怎么写文档的应该占很大一部分比例。
- 太忙没时间写或者懒得写
程序员确实很忙,但总有不那么忙的时候,却也很少见有人利用这时间去写文档。包括我自己也这样,有时候没那么忙的时候,宁可去想想怎么重构下代码,却很少会愿意去写文档,主要还是太懒。
- 因为是敏捷开发,所以不用写文档?
对于这个问题,我其实反驳过多次,敏捷宣言 最后一句话明确指出:「尽管右项有其价值,我们更重视左项的价值。」也就是说敏捷从来没有否认文档的价值,只是更重视 「工作的软件」 罢了。
1.2 为什么要写技术文档?
写文档,其实对个人、对项目、对团队,都是非常重要的事情。
1.2.1 理清思路
我想你应该有这样的感受:写作的过程,就是一个思考的过程。
写文档,可以让你在写代码之前,梳理清楚思路,想清楚整体结构,比如说有哪些工作是重点难点;哪些要依赖其他人,需要及早协商的;哪些是要考虑安全性的。
如果上手就写代码,就很容易陷入到某个技术细节中,而忽略了整体结构。写的时候才发现一个技术难点无法解决,或者已经在某个不重要的细节上浪费了很多时间;或是发现有些依赖其他人提供的服务还没准备好;又或者是上线后才发现有安全漏洞。
先写文档,就会抛开代码细节,去站在全局思考。写的时候,各个模块之间的依赖关系、各种可能的安全隐患、各种可能需要其他人配合的地方,就都冒出来了,必须要去查资料,去找人讨论,反复缜密的思考后最终写出来。
其目的是迫使你对设计展开缜密的思考,并收集他人的反馈,进而完善你的想法
换个角度来说,如果你连文档都写不出来,那又怎么能指望代码写得好呢?
1.2.2 便于维护和交接
「好记性不如烂笔头」,存在脑子里的内容是不可靠的,一个正常的项目组,如果需要长期维护,就需要一定的文档,把设计、操作流程、环境配置等内容记录下来,而不仅仅依赖于 口口相传。
1.2.3 便于协作沟通
在一个项目组中,大家都有不同的分工,有人负责产品设计,有人负责架构设计,有人负责测试。而文档,就成为了团队成员很好的沟通工具。
比如说产品设计有雏型的时候,会有一个产品设计的评审会议,基于文档,项目成员可以一起参与其中,提出自己的意见和看法。这样就不至于等到产品设计出来之后,大家才对于设计有改进想法或意见,造成无法更改的结果。
1.3 技术文档的注意事项
我参与过很多次设计评审,经常会发现如下问题:
- 文档工具不统一,不同的小组、部门存在差异,有些甚至不知道是什么格式的文件,无法打开;
- 过度拷贝需求文档,缺少软件设计的内容,不像软件设计文档;
- 排版混乱,设计文档未按照标准模板顺序,缺少清晰的目录结构;
- 设计文档太多图片,有些质量很差,且缺失原始文件,比如 EA 工具做的缺乏 eapx 文件,会导致文档迭代需要全部重新绘图,久而久之更加不愿意去维护更新文档了;
- 没有统一的文档版本管理工具,缺少追溯和统计管理的能力;
- 数据库表结构设计样式杂乱不统一,字段无中文描述(毕竟母语不是英语),且基本没有考虑主键和索引设计;
- 程序流程基本比较简单,缺少主线,无法描述核心算法及关键点 (例如各种校验、事务、并发、缓存等处理);
- 类图缺乏体现类之间的关系,有的直接用英文函数名,缺乏描述;
- 时序图大多只描述与数据库的交互,缺少业务流程和程序执行的时序图;
- 不理解设计文档的意义,很简单的任务需求就不需要写设计文档了;
- 缺少对安全、性能、边界情况、性价比的思考,考虑还不够全面,评审把关不严;
总结了几点需要注意的问题给大家参考:
- 文档撰写人:架构设计师或功能的开发者;
- 明确文档面向的读者:是部门内部的开发者?伙伴实施人员?外部的开发者?
- 设计先行:设计文档在撰写应该是在编码之前,可以极大的避免后期出现返工的情况,也能提升开发效率;
- 一图胜千言:尽可能的使用图文的方式表达清楚设计思路;
- 统一的绘图工具:需要支持导入及导出,方便后续更新;
- 统一的文档模板:为了防止出现千奇百怪的文档、排版不一致、难以阅读等的问题;
- 确定承载的形式:可以从安全性(文档加密)、便于查看、版本管理等方面考虑,推荐内部的知识文档管理系统、类似 wiki, git, svn 的版本管理工具、内网微盘;
- 好代码优于设计文档:有时候写出优雅的代码和注释更胜于写一篇设计文档;
- 版本迭代:在软件功能迭代的过程中,可能经过几次迭代后功能和设计有了很大的变化,设计文档应该及时更新,以免给人传递错误的信息;
2. 如何写好技术文档
2.1 方法论
2.1.1 5W 法则
5W 法则相信大家已经听的多了,分别是 Who、What、When、Where、Why。这是一个广泛被用在各行各业的法则,写文档当然也不例外。
Who:文档的针对对象是谁,读者是谁。
What:明确文档写作的用途,通常仅需说明文档的用途和目的就能帮你搭建起整个文档的框架。
When:明确文档的创建、Review 和更新日期。因为文档也有时效性,明确相关日期可以避免阅读者踩坑。
Where:文档应该放在哪!建议一个组织或者团队有统一的永久文档存放地址,并且有版本控制。最好是方便查找、使用和分享。
Why:为什么要写这篇文档, 你期望读者读完后从文档中获得什么!
2.1.2 金字塔原则
我知道这是小学作文里都会用的套路。但是,it works。对了,比较专业一点的说法是叫做 金字塔原理。
金字塔原理:
1 | 中心思想1 |
2.1.3 从模仿开始
2.1.4 从小文档开始
从一个小的技术实现细节开始, 到整个技术方案, 再到系统的技术方案。
2.1.5 从粗到细, 迭代更新
大纲由于细节.
详细的技术文档要花很多时间精力,甚至可能写不下去;另一个原因就是在收集反馈的过程中,会有很多修改。写得越细则无用功越多,最后,你甚至会因为不想改文档而抵触不同的意见。
而从粗到细逐步迭代的方式就好多了,一开始的目的是为了梳理清楚思路,只要脑图这种级别的内容就好了,然后进行调整。因为文档很粗,调整也方便,等到基本确定后再写细节,就不会有大的反复。
2.2 排版
文档排版我放在比较重要的位置, 因为我只要看到排版特别乱的文档就直接放弃阅读, 这也是为什么我不愿意接受或使用 Word 来写技术文档的原因(因为会花费大量的时间在排版上)。
这里简单的罗列一下好的排版:
- 避免低级错误:避免出现错别字、词语误用、标点符号错误等现象;
- 首行不用缩进:小时候老师经常教我们首行缩进,但是个人建议不缩进,因为你不是写论文;
- 段落区分:通过「空一行」来区分段落,并且每个段落的文字不要过长,否则你会发现一堆的文字堆砌在一起,密密麻麻的让人失去继续阅读下去的兴趣;
- 保留空格:当英文、数字和中文相遇的时候,他们之间要 留一个空格,这样阅读起来会更舒适;
- 专有名词:很多人把 Java 写成 JAVA,MySQL 写成 mysql,会显得很不专业。
首行缩进和段落区分:
当英文、数字和中文相遇的时候:
2.3 常用工具
- Markdown: 基础语法
- Typora: Markdown 编辑工具
- draw.io: 跨平台的画图工具; IDEA、Visual Studio Code 插件
- Figma: 原型工具
一般来说,只要别人发给我的文档是一份 Word 文档,我基本就把这份文档排在了最 Low 的一档。对于这种文档,我就想问三点:
- 文档有更新怎么分发给每个需要这份文档的人?
- Word 格式不兼容导致关键图表排版混乱怎么办?
- 代码因系统不同存在的换位符不同导致的错误问题怎么解决?
不知道大家多年前有没有被 Windows 文本编辑器的 BOM 搞得鸡飞狗跳?
对于 Word/Pdf 我是极力排斥的,因为很多文档都是需要更新的,这两种格式没法做到动态更新 。
2.3.1 为什么用 Markdown
- Markdown 时下最为火热的文本标记语言,是目前官方文档、技术博客中最主流的文档编排方式;
- 不需要花费很长的时间学习 Markdown 的语法,它的语法真的非常简单;
- 专注于文档编写,尽量少的精力关注复杂的格式。除一些项目设计书外,比较建议用 Word 来编写,绝大多数指导类文档、环境配置指导等文档都推荐使用 Markdown 来书写;
- 专注于文档内容的编写,无需过多关系文本格式,支持跨平台文档,不需要考虑兼容性;
- 更加符合程序员的编程规范,像编程一些编写文档,像代码工程一样演进文档;
- 在项目开发中常常会需要编写
REAMDE.md
文档,特别在 Github 的开源演进中;
Markdown 比较受开源社区的欢迎,因为它在表达力和简洁性之间找到了一个平衡点,但是它有一个致命问题就是 无法应付稍微复杂一点的排版。
2.3.2 为什么使用 draw.io
draw.io 当前已经改名成 diagrams.net,是一款免费的在线图表编辑工具,可以用来编辑 BPM, org charts, UML, ER 图, 网络拓朴图等各种覆盖的图。
类似于 ProcessOn 的在线画图平台,但是 draw.io 跨平台 且完全免费。支持在线直接画图,chrome 插件客户端,桌面客户端。
推荐使用 draw.io 绘图,导出为 svg 图片,而不是直接使用截图, 原因有 2 点:
- svg 是矢量图, 无限放大不失真;
- 可在原来的基础上再次编辑;
列举了一些参考资料:
2.4 配图技巧
一图胜千言, 无图无真相
- 配图下面加上一些图片的关键描述
- 使用 svg 代替 png
- 不要讲背景设置为网格
- 整体使用低饱和颜色即可, 关键的地方可适当使用高饱和颜色
2.5 引用/参考资料
- 相关需求单:比如某个业务所有相关的需求单都放在这里,方便其他人更进一步了解背景,也方便自己查找。
- 参考资料。
2.6 变更历史
变更日志,一般开源项目都会记录每个版本的重要变更。
文档变更记录:
2.7 维护工具
对于文档的管理,我推荐使用 Git,像管理代码一样管理文档。另外我推荐使用一个静态网站来存放自己的文档,这样其他同事访问的时候看到的总是最新的文档。
3. 概要/详细设计
在写软件概要/详细设计说明书时,首先应该明确读者是 专业的开发人员,文档应该严谨细致,专业性强。
其次应该明确软件概要/详细说明书的设计依据是需求规格说明书,需求规格说明书中的要素应该能够与软件概要/详细说明书中的要素完全对应,即符合需求追踪表。
软件概要/详细设计说明书是从技术实现的角度将需求规格说明书进行展开,形成描述软件架构的文档。软件架构应该是按照「MECE 原则」拆分为多个模块的多层次的结构,这些模块能够完全穷尽需求规格说明书中的要求,同时又相互独立。使用 UML 图描述类图、结构图。
软件概要/详细设计说明书还需要写动态过程,借助流程图[泳道图、状态图,写清楚软件模块的执行过程。
软件概要/详细设计说明书拟制结束后,应该是多个互相独立解耦的模块,这些模块就可以分配给不同的程序员同步进行开发。
4. 总结
那么什么样的文档才称得上是一个好的文档? 我认为应该满足以下几点:
- 高度可维护的并且经常维护;
- 易于理解:表达准确、结构清晰、排版美观、风格统一;
有哪些方法论和工具能帮助我们去提供文档质量:
- 多看优质的技术文档, 学习写作大纲、 配图、排版;
- 多构思, 多写, 多练习, 形成一套自己的感谢做方式与方法;
- 使用业内常用的、跨平台的工具, 一个团队最好全部统一;