最近因为个人兴趣,我一直在折腾一个小型软件项目。
我不是程序员,很多东西都是边做边学。
真正做了一段时间以后,我慢慢发现,一个软件项目想长期稳定地做下去,光把功能开发出来远远不够。
更麻烦的事情,其实是:怎么把这个项目“管住”。
一、代码写出来以后,事情才刚刚开始
项目做到十几个版本以后,我开始给它整理各种文档。
有一类文档,记录系统最核心的业务逻辑。我把它叫作项目的“基本法”。
它不负责记录某一次具体修改,而是规定这个系统现在到底应该怎么运行,哪些核心原则不能轻易破坏。
还有一类,是工程和技术基线。
比如项目运行在什么环境,目录怎么组织,数据库是什么版本,版本号怎么编号,升级包怎么打,哪些文件承担什么职责,开发过程中哪些规则必须遵守。
再往下,是每一轮具体的开发需求。
为什么要改,准备怎么改,这一次修改的边界在哪里,最后按照什么标准验收,都要留下记录。
最后还有更新日志和验收记录:
哪个版本实际修改了什么,哪些问题已经解决,什么时候部署,最后有没有通过验收。
整理到这里的时候,我突然产生了一种非常熟悉的感觉。
这不就是工程项目里的资料管理吗?
甚至我突然理解了,为什么一个施工项目一定要有资料员。
二、资料员管理的,其实是项目的“记忆”
以前看工程项目,容易觉得真正重要的是现场施工、技术、进度和成本。
资料员好像只是收文件、填表格、整理档案。
但真正自己做过一个不断迭代的软件项目以后,我才发现,资料员实际上维护的是复杂项目最重要的东西之一:
可追溯性。
工程项目每天都在变化。
图纸会调整,施工方案会修改,会产生设计变更、技术核定、工程联系单、会议纪要、隐蔽验收、检验批、材料报验,最后还要形成完整的竣工资料。
如果这些东西没有人持续管理,很快就会出现问题。
现场已经按照新版图纸施工了,办公室里留的却还是旧图;
某个地方明明已经变更,大家当时也都知道,但过几个月以后却找不到正式依据;
甚至工程已经做完,到了验收、结算的时候,才发现资料和现场对不上。
软件开发其实一模一样。
代码已经改了几个版本,但业务规则文档没有同步;
某个功能为什么这样设计,当时讨论得很清楚,过几个月却只能翻聊天记录考古;
一个新版本已经部署了,但是更新日志没有记完整;
更严重一点,开发人员甚至可能拿错代码基线,用一份旧文件把已经修好的新文件重新覆盖掉。
这些问题单独看都不复杂。
但只要一个项目持续时间足够长,它们就会不断累积,最后从“小问题”变成真正的管理问题。
三、把程序员的“黑话”翻译成施工语言
后来我发现,如果把一些软件开发术语直接翻译成工程项目里的概念,其实非常容易理解。
比如:
编码(Code),可以大致理解成施工现场真正实施的东西。
当然写代码和实体建筑并不能严格一一对应,但它是最终让系统实际运行起来的主体,就像现场最后真正被施工出来的工程实体。
需求(Requirement),很像建设单位提出的使用需求和建设目标。
我要这个系统增加什么功能,解决什么问题,本质上类似“这个项目最后要实现什么”。
设计(Design),就很好理解了。
软件也不能拿到需求以后直接开干,同样要考虑系统怎么组织、数据怎么走、不同功能之间怎么衔接。
它和施工图设计的逻辑非常相似。
开发(Development),可以近似理解为施工。
把设计真正变成能够运行的东西。
Bug,就是质量问题或者缺陷。
有的是表面小毛病,有的是功能性问题,有的则可能影响整个系统运行。
测试(Testing),很像检查、检测和验收。
设计上认为应该能工作,不代表实际做出来就一定正确,仍然需要一项一项检查。
版本(Version / Build),则很像工程资料里的版次。
同一份东西不断修改以后,必须能够明确现在执行的是哪一版。
否则“我记得以前不是这样的”这种事情很快就会出现。
技术基线(Baseline),我觉得特别像工程管理里的一个重要概念:
现在大家究竟以哪一套正式资料作为工作的起点。
当前使用什么环境、什么数据库、什么版本的代码、哪些文件有效,都必须确定。
如果基线都不一致,后面的所有修改就失去了共同基础。
Git,也就是代码版本管理工具,如果一定要用工程语言解释,可以把它想象成一个极其严格、几乎什么都记得住的电子档案室。
谁在什么时候修改了什么,增加了哪一行、删除了哪一行,理论上都可以追溯。
而软件里的 Commit(提交),某种程度上就像给一次正式变更留档:
这一次到底改了什么,形成一个清楚的历史节点。
Changelog(更新日志),就更加接近工程里的变更和实施记录。
计划修改什么是一回事,最终到底实施了什么,是另外一回事。
至于软件项目里的 文档管理,越做到后面,我越觉得它和工程资料管理几乎是同一种思维。
只是一个管理的是钢筋混凝土背后的建设过程,一个管理的是代码背后的开发过程。
四、软件项目也需要自己的“工程资料”
我后来越来越觉得,软件开发里的项目文档,其实就是一种数字化的工程资料。
比如可以简单分成几类:
第一类,是“基本法”。
记录系统当前有效的核心业务逻辑。
它解决的是:
这个系统现在究竟应该按照什么规则运行?
第二类,是工程和技术基线。
记录运行环境、数据库、目录、版本规则、开发规则等。
它解决的是:
我们现在到底站在哪一个工程基础上继续往下做?
第三类,是开发需求档案。
记录为什么提出这次修改,当时讨论过哪些方案,最后决定怎么实施。
它解决的是:
当初为什么要这么改?
第四类,是更新和验收记录。
记录最终真正实施了什么,哪个版本生效,测试和验收结果怎么样。
它解决的是:
最后到底改成了什么?
这么分类以后,整个项目一下就清楚了。
因为“现行规则”“修改原因”“实施过程”“最终结果”终于不再混在一起。
五、最怕的不是变更,而是变更以后没有记录
施工项目不可能完全不变。
软件项目更加不可能。
今天觉得合理的方案,做到下一阶段可能发现需要调整;新的需求出现以后,原来的设计也可能必须修改。
所以真正成熟的管理,并不是拒绝变化。
而是保证每一次变化:
有依据、有记录、有版本、有结果。
工程项目里,如果现场改了做法,却没有同步设计变更、技术核定和竣工资料,最后一定会留下麻烦。
软件项目也是一样。
代码变了,文档却没变;
需求变了,规则却没变;
系统已经运行到了新版本,项目资料却还停留在几个版本以前。
时间一长,人就会逐渐失去对项目真实状态的掌握。
六、我终于理解了资料员为什么重要
也正因为如此,我现在重新理解了资料员这个岗位。
资料员并不只是“整理资料的人”。
一个好的资料员,实际上是在帮助整个项目保存记忆。
他让今天做出的决定,半年以后仍然能够被理解;
让现场发生过的变化,最后能够形成完整证据;
也让一个复杂项目不会因为人员变化、时间推移和大量细节不断堆积,最终失去自己的历史。
我本来只是出于兴趣做一个小软件。
没想到做着做着,反而让我对现实中的工程管理有了新的理解。
软件开发和建筑施工看起来是两个距离很远的行业。
一个面对的是代码、数据库和服务器,一个面对的是图纸、机械和钢筋混凝土。
但只要项目开始变得复杂,它们面对的问题其实越来越相似:
谁提出需求,依据什么设计;
现在执行哪一个版本;
中间发生过哪些变更;
最终实施的结果是什么;
以后出了问题,还能不能找到当时的依据。
所以现在再看“资料员”这个岗位,我会觉得这个名称其实有点低估了它真正承担的职责。
资料员管理的不是一堆文件,而是一个工程项目的记忆。
而复杂项目真正需要管理的,也从来不只是“把事情做出来”。
还要让整个过程始终有据可查,让后来的人能够知道:
它为什么会变成今天这个样子。
