目录
1、问题起源
2、解决方案
2.1、需求和代码对应
2.2、每日检查
2.3、飞行检查
2.4、公共模块
3、补充说明
4、遗留问题
文档代码同源,故名思意,就是文档和代码都写在源代码文件里。这样可以: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 ,感谢大神的经验分享~