文档代码同源

文档代码同源,故名思意,就是文档和代码都写在源代码文件里。这样可以:

1、修改代码的时候就及时修改文档,使得文档和代码及时保持一致;

2、阅读代码时,增加代码的可读性。评审代码的时候,尤其是修改时后,即对文档一同评审。结合研发流程、评审的配合,可促使代码、文档的开发逐步走向一一对应,逐步向高质量发展,同时也能提高团队素质。

1、问题起源

互联网行业和一些物联网行业,软件开发都提倡敏捷开发,敏捷开发为何物?(附件介绍。)这里列出敏捷的宣言:

个体和互动高于流程和工具

工作的软件高于详尽的文档

客户合作高于合同谈判

响应变化高于遵循计划

也就是说,尽管右项有其价值,

我们更重视左项的价值

很多公司所谓的敏捷,很大程度上就是开发代码,应该有的必要文档可能都是不全的。因为要赶工,因为市场的巨大压力,文档代码对应不上司空见惯。更有甚者,压根就没有文档。这里造成了很多隐性的问题。

1.没有合适的文档,随着时间的推移,一些技术要点,设计要求,设计思路随着时间,尽归尘土。这些通过市场、技术、商业等各个维度试错的来的宝贵经验和知识无法传承,是一种浪费,更是一种低效组织的表现。

2.关键岗位的开发人员一旦流失,产生的技术、知识断崖,短期内难以补足。

3.新人的进入,需要长时间的消化理解。

4.代码的评审和检查不严格,想怎样改就怎样改,只要外在的功能是正常的。那就是没有问题的。为很多问题埋下了伏笔和隐患。

敏捷中有一个观点,窃以为是无比正确的:没有什么文档比代码更准确。但这个观点又是比较危险的:

1.可运行的功能正确的代码的确是没有什么比其更准确的了。但是,代码毕竟是写给机器运行的,个人的能力、习惯等都不一致,其他人理解起来必然费劲。有一些饱含技巧的写法可能是需求的需要,也可能是个人炫技的需要;其他人又怎能看透全部呢?代码毕竟是非自然语言,有时候能看得懂代码,是以牺牲速度为代价的,总之,问题比较多。

2.潜台词是,文档不重要。

总之,文档、代码的问题,不仅困扰着程序员,也困扰着公司。那么怎么找一个合适的方法解决这个问题呢?

2、解决方案

想想程序员为什么写或修改代码?我想即使是为了拯救地球和全宇宙,从微观上讲,也符合下列情况之一:

1.实现需求。是的,这怕是程序员写/修改代码的第一大原因了。

2.抓 Bug。程序员实现需求的副产品:八阿哥(bug)。把它送走,是我们改代码的第二大驱动。

3.其他原因,诸如设计不足,可理解性不好啦,模块用起来不爽啦,封装不够简洁实用,有一些程序员还有洁癖。这可能都是修改代码的原因。但从本质上来讲,也是满足需求的修改。每个产品需求定义之外,都有灰色边界。需求提得越清楚,灰色地带就越少。阅读性不好、模块用起来不爽,可能在需求里没有提出来。有些作为需求提出来,也是可以的。比如说,对于产品某个模块的要求,必须使用什么标准技术或模块,或者必须满足下一代的复用等。至于洁癖,团队没有定义团队的写法,那么冲突修改是必然的。

代码中所有的修改都可归为这三类,更进一步,大部分应该是前两类。开源世界有一个很好用的工具是 Doxygen。它的作用就是把代码里的特殊注释抽取出来变为文档(一个类似 Latex 的工具,非所见即所得的文档编辑工具)。我们的思路就是,利用 Doxygen 工具,将代码和文档的开发变为同步过程。由于文档含在代码里,也意味着 Doxygen 的文档也是文本,在版本库的管理下,能精确的看到每一个比特的修改。(后面有文章做一个的 Doxygen 介绍。)这里简单的介绍一下 Doxygen。

Doxygen 是一个程序的文档产生工具,可将程序中的特定注释转换成为说明文件。比如说对于以下这段注释:

以上经过 Doxygen 抽取编译后,会生成一个综合性文档,可在里面查到:

即使我们不用 doxygen 编译,写在代码里的注释,也是不影响我们理解的。只是编译后,查阅起来更方便。

这是我们实现文档代码同源的基础。但文档代码的同源不仅仅是把代码和文档合成一个源代码文件。我们要做得是:

1.需求要和代码中的各个实现模块对应起来;

2.文档的修改、代码的修改同步进行,每天由工程师交叉检查并给出评语;

3.高级技术人员定期整理代码问题,形成案例;

4.如果是公共模块,项目进行过程中,定期整理其 Bug,问题,维护其可用性。

2.1、需求和代码对应

开发一款产品,首先要提需求,需求开发出来,大抵是这样的:

需求提出了方方面面的要求,一般,需求的分配表也跟在后面,用于指示这个需求都由那些模块实现。

紧接着下来是软硬件的概要或者详细设计,有些公司为了节省,就只有设计;有的干脆就连设计也省了,走“敏捷"路线。这个并不重要。

Doxygen 支持自由页面,可以写一个 Python 的小工具,将 excel 的需求表转化为 txt 的文本文件,被 doxygen 所识别。

这样做得好处:

1.需求只要经常用版本库追踪,谁改了一个字,改了什么都会清清楚楚。

2.程序员查阅需求会更加简便。同时,每日的检查强调,需求的修改,可能会带来代码的修改;Bug 的修改可能带来代码的修改,需求的修改。从而强调需求的定义作用,主动维护需求的前后一致。

如模块中编写时,说明实现了哪些需求。

这些都是超文本标签,点击后迅速转到需求定义处可查看。

2.2、每日检查

该方法的核心内容,就是每日检查。一个程序员每天的代码产量最多可达上千行(非每日平均产量)。如果是更改 Bug,可能一天大部分的时间用于分析跟踪上。正真的修改并不多。每日提交版本库后,由其他程序员或者部门经理检查代码及修改,检查的内容如下:

1.代码修改是否有效,符合组织内部的规定;

2.文档和代码是否对应。

与需求类似,写一个 Excel 表格,包含:模块;检查人;日期;问题描述的跟踪表;检查完成后提交至版本库,由对应的工程师承接修改。

每次检查,检查文档、代码的问题,通过版本库可以很轻松的跟踪相关的修改。并定位修改是否合理。

2.3、飞行检查

为了防止检查流于形式,定期对一些具有代表性的问题做总结。高级技术人员需要做一些飞行检查,定期的抽查检查表以及文档代码的对应情况。并从问题中选出有代表性的案例,收集成案例,用于团队的提升和警示。

2.4、公共模块

一个有积累的公司,应该不会从 0 开始构建自己的项目。总是多多少少有些积累的。代码同源的模块如何被复用呢?首先,公司内部要有完善的版本控制机制。任何代码,全局只有一份。对于 svn 的版本库、git 的版本库,有不同的办法。(svn 可以使用 externals 属性,保持全局唯一的库文件。git 可以使用 subtree, submodule 的办法建立全局唯一的库文件。)由于库代码导出后,文档和库跟着走的,也不存在这不对应的问题。如果发生库的修改,因为全局就一份库的代码。更改完毕,全局都会跟着修改。所以,库的提交需要更为慎重。需要建立更为严谨的修改确认机制。

无论怎么更改,只要每天保证文档、代码对应。下载最新的源代码,使用 Doxygen 编译,则可得到最新的文档。

3、补充说明

文档代码同源的思路,可解决实践中的文档代码不一致的问题,但这不是最终目的。长期坚持,达到一个良好的开发习惯和开发氛围。从而提高项目交付质量和内部的管理水平。达到组织和个人的共同成长。

4、遗留问题

这个方法,是有适用范围的,我在软硬结合的项目以及一些纯软件的中小型项目上实施,取得了一些比较好的效果。尚未在比较大型的项目上使用。

另外,方法也需要不少工具配合。

1.如果内部没有需求管理工具的厂商,可以直接用 excel 管理,然后自己写个 python 工具转换一下。如果内部有需求管理工具的公司,应该都可以将需求导出成 excel,然后通过工具转换成 doxygen 接受的文档。

2.内部的检查一定要每天坚持,这才是核心中的核心。每天并不耗时,但是却很重要,量变引起质变。

3.库的管理需要 svn、git 等版本控制工具的强力支持,这个需要被管理公司有一定的版本管控水平和能力。

本文原创: coolbacon RTEMS,感谢大神的经验分享~

  • 发表于:
  • 本文为 InfoQ 中文站特供稿件
  • 首发地址https://www.infoq.cn/article/0d79d506f47c416c4e3e143dd
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券