交付工程(Release Engineering)基础——特性冻结和代码冻结
许多参与过大型项目开发的读者可能都经历,至少是听说过特性冻结和代码冻结这样一个概念。所谓“特性冻结”实际上是一个开发者之间的约定,在这个阶段中,不再允许添加新的功能。
特性冻结(Feature Freeze)通常在一个开发分支(Development Branch)跃变为交付分支(Release Branch)的时候开始。之所以需要特性冻结,是因为增加新的特性很有可能引入新的问题,而这将给代码复审带来沉重的负担,甚至导致一次不成功的最后交付。
当然,对于那些已经明确地定义了特性表的小型软件工程项目(例如,传统的瀑布开发模型)来说,特性冻结没有什么意义,因为在这些工程中,详细设计完全是在编写代码之前进行的,这意味着,代码将要写成什么样子已经在详细设计中明确地定义。但在实际的项目中,详细设计往往会包括两类不同的类型要求——一部分是“必须实现的特性(Must have feature)”,另一部份则是“希望实现的特性(Desired Feature)”。在交付之前,所有“希望实现的特性”都会在特性冻结时被明确成“实现特性”和“不实现特性”。
我们注意到,这种情况下,某些特性被延迟到接近交付的时候才被明确成“必须实现”,而另一些“希望实现的功能”则被作为“不实现”,从而转化为我们先前熟悉的样子,即详细设计文档中明确地定义了软件中的所有特性。
这样做的结果是软件工程项目具有更大的灵活性。由客户需求产生的功能设计,很显然地,应该列为“必须实现的特性”,而那些开发团队提出的能够提高软件整体可扩展性、可伸缩性或其他性能的特性,则应列为“希望实现的特性”。在特性冻结之后,整个开发团队将专注于那些“实现特性”(尽管这些特性可能还没有被正式的实现)更加稳定,从而将生产出更高质量的软件。
根据我个人的经验,特性冻结应该发生在预期编码时间已经用去大约2/3的时候。这时,项目经理应该组织开发人员举行一次会议讨论特性冻结,而在特性冻结之后,在软件正式交付之前,任何开发人员都不应该再去考虑那些被列为“不实现特性”的功能。
代码冻结是一个与特性冻结类似的概念,在这个阶段,只允许对被冻结代码分支中的错误进行修正,而不允许任何其他的、涉及功能的修改。实践上,这个过程中,只有交付工程师(通常是一个或多个对于整个系统架构非常了解的、有丰富开发经验的代码复审员)被授予审查和批准代码提交的权力,任何代码修改,只要没有经过交付工程师的批准,就不能被提交到代码库中。
代码冻结的时间一般不需要太长。对于中等规模的项目,这一过程通常会持续一至两周,对于大型项目,这一过程则有可能持续一个月甚至更长的时间。在这个阶段,交付工程师主要负责代码复审,而测试工程师则有责任及时反馈集中的测试中暴露出的问题,并与相关的开发人员联系、解决这些问题。
技术上,代码冻结可以通过修改cvs中的配置来实现。不过,更好的办法是通过制度来保证代码冻结。
交付工程——编码阶段的总结
交付工程的好坏在某种意义上,是直接关系到用户利益的部分。前面已经说了相当多的关于软件开发过程中通过版本控制技术来提高开发效率的技巧和方法,这里我将继续说一说交付工程。
前面提到了每日构建中在代码上适当地打上版本标记,以及在划分版本分支时在切分点上增加版本标记,这些对于交付工程都具有非常重要的意义。交付工程,在软件工程项目中是一个融合了代码复审和集中测试的重要阶段。
交付工程的一般程序
在项目进行到某个特定的阶段,交付工程师同其他主要的项目管理者商议决定宣布代码冻结和交付工程开始。
交付工程师对代码进行集中的复审,而测试工程师则组织进行大规模的集中测试。
交付工程过程中,交付工程师每隔一段时间发布一个“交付候选版本(Release Candidate)”,测试工程师跟随安装并测试这些交付候选版本。
此间,测试工程师随时向交付工程师反馈问题,交付工程师将问题分类、整理,并约见相应的开发人员,予以解决。
最终,某个“交付候选版本”被最终指定为交付版本(Release)。代码冻结结束,软件被交付给客户。
一些读者可能已经注意到,交付工程的绝大多数任务事实上已经被融入了我前面所描述的开发过程——在编码阶段的整个过程中,代码复审、问题反馈和测试一直是持续地进行的,只是,在“交付工程”阶段,代码复审和测试被提升到了一个更为核心的地位,在这一阶段,开发的重要任务是查错和排错,而不再是将软件的功能推向一个崭新的水平。