在写这篇文章之前,我曾天真地认为 ASPICE 和敏捷开发最大的区别在于:文档和条目化。而二者融合的最大挑战在于:如何将汽车工程师习惯的文档,转化成条目化的结构。不过,在与上百家客户进行深入地讨论之后,我逐渐认识到,以上只是挑战之一。事实上,二者之间,还有更多底层认知层面的挑战。

ASPICE 流程中的版本管理:初衷与实现

在 ASPICE 流程中,版本管理的核心目标是确保开发过程的稳定性和可追溯性。通过严格控制需求、设计、代码等文档的版本,ASPICE 希望在开发过程中建立清晰的基线,以便在出现问题时能够快速追溯到问题的根源。这种做法在理论上是无可厚非的。

到此为止,上述流程都没有任何问题,运行得非常完美,大多数团队都能顺利执行。接下来,是这个流程中的 hard 模式。

当确定了接下来一段时间的基线之后,团队进入开发阶段,假设距离发版截止日还有 1 个月时间。假设开发的过程中,基线不存在任何变化,那么一切就都太 "完美" 了,直接基于基线中的需求、架构设计、测试用例执行完就好了。

但实际工程项目中,这种 "风平浪静" 的开发模式,永远也不可能存在。大部分时候,这一个月内会发生很多变化:发现设计文档考虑不全面需要修改、客户要求增加新需求、客户要求修改原需求、竞争对手推出新功能产品经理想紧跟潮流……

此时,团队有两种选择:就在当前基线立刻开始执行变更流程,或者等待当前基线结束,在下次基线中加入上述变化。

版本管理的 "魔鬼地狱"

假设团队选择在当前基线立刻开始执行变更流程,团队有如下 3 种处理方案:

方案 1:整个基线 v1 全部复制一份到 v1.1,在其中需要更改的文件上直接更改,邀请 CCB 评审

优点:操作方便,整体全部复制一份。

缺点:每次变更都需要复制整个基线,随着变更次数增多,基线版本越来越多,系统速度变慢;难以比较任何两个基线版本的差异;如何选出受变更影响的其他文档并一起改变,是难点,系统往往很难自动识别出变更受影响项,需用户手动识别,遗漏风险非常高。

方案 2:把其中需要修改的文档 v1.0 拿出来,改成 v1.1,邀请 CCB 评审,作为补充文件和基线 v1 构成一个整体

优点:只选择需要修改的文档,文档数量不会急剧增加。

缺点:难以保证后续真正实施变更的用户,在看基线的同时也注意到变更,导致实际实现与基线有差距;如何选出受变更影响的其他文档并一起改变,同样是难点。

方案 3:把其中需要修改的文档 v1.0 拿出来改成 v1.1,用户在基线 v1 内查看需求文档时第一眼就看到 v1.1,不能看到 v1.0 版本

优点:继承了方案 2 的优点,且避免了方案 2 的缺点 —— 实际执行变更的用户第一眼看到的是变更后的内容。

缺点:难以比较任何两个基线版本的差异;一个需求有了多个版本,加入基线时的 v1.0 版本和变更之后的 v1.1 版本,对于需求的状态推进、责任人管控都是难点。

到此为止,无论是采用哪一种变更管理流程,都有不小的挑战。此外,团队还面临着另外一个挑战:评审通过后的文档,阶段性定稿加入到基线中进行归档。而各类文档本身不会就此停下来,而是还在持续更新。 此时,任何一份文档都有了多个实体:不断变化的本体,以及被加入到各个基线中用于存档的复制体。同一份需求文档,每条需求在不同的基线中,责任人可能不同、状态可能不同。如何来定义需求的真正责任人和状态呢?

这就是为什么那么多严格遵循 ASPICE 的团队,主观上不愿意,或者客观上难执行变更的原因。那就不变呗,在下一次基线中再进行变更。那一次基线的开发周期是多长呢?3 个月或者更长。也就是说,3 个月内,尽量不要响应变化!

10 年前,德系车企和供应商大抵都是这么做的。上述整个流程分析也说明了为什么 "经典" 的 ASPICE 理论和工具链,事实上无法很好支撑变更。

什么是 "伪基线"?

相信已经有很多读者被我上述描述的基线与变更流程吓到了。于是,有人想到了一个好方法:既然打完基线之后变更这么麻烦,那么我是否可以在开发完之后,再打基线呢?

比如规定 5 月 30 号要发版,从 3 月 1 号开始,需求、架构、详细设计、测试用例、代码都在不断修改,直到 5 月 28 号集成工程师编译出一个软件包,经过测试之后发现这个包基本没什么大问题了,此时再把需求、架构、详细设计、测试用例以及所有的其他文档及软件包,都打包成一个整体,放入到基线中。

这种方法打出来的 "基线",应该换个名字,叫 **"阶段性快照"**。而此快照不是用于团队基于此做开发的,而是用于查看阶段性实现状态的。因此不具备 "Baseline" 的意义,也不存在在上面执行变更的需要了。

我暂且将其命名为 **"伪基线"** 吧。它只是用于给甲方客户以及评审老师一个交待,仅此而已,不具备任何指导开发的作用。