活用 XP: (二)考核和评估之别
林星(转载自www-900.ibm.com) 2003年10月27日
螺旋、迭代、增量,不同的名词代表了同样的含义-分阶段开发软件。众多的方法学都采用了这种思路设计软件过程。但是在实践中,更多时候,分阶段开发软件带来的是痛苦。看来,我们常常被书中优美的叙述所迷惑,却没有真正想过实施中的难题。那么,如何管理分阶段的软件开发呢?如何应对现实中的难题呢?
考核和评估之别
在绩效管理中,有两个名词:考核和评估,分别表示了绩效考核和绩效评估两种绩效管理方式。这两者有什么区别呢?
我们说考核是一种制度,而评估是一个过程。怎么理解呢?很多的公司都有绩效考核的制度,这个制度一般是在年底的时候,对员工今年的工作做一个评定。考核是一个点。但是评估不一样,评估是针对某一段时间中员工工作中的不足之处,需要改进之处进行评价。不论是考核还是评估,它们两者虽然都是为了达到评价并改进员工行为的目的而设计的,但是做法是不同的。考核针对过去的事情进行评定,容易实现,但是效果不佳,因为时间一长,大家可能忘记了以前的事情,而要公平的对过去一年的表现做一个评定也不是一件容易的事,评估则不同,评估是不断进行的,针对刚刚发生的事情做出评价,并找到改进方法。就好像我们在第一章中举的外卖店的例子,不断地对过程进行分析和改进,这就是一种评估。评估的效果不错,但难以实现。
软件开发中的考核和评估
这一思路在软件过程中,直接表现为里程碑和迭代的思路。我们可以想想,里程碑是不是一种制度。在需求结束的时候,我们需要需求规约文档,风险列表等等一系列的文档,在设计结束的时候,我们也需要另一些文档。这种处理方式就是考核的思路。但是很多时候,这种考核起到的作用是有局限性的:
工件的设计原本是为了辅助生成最终的代码,但是往往会演变成为了通过里程碑而设计;
里程碑的设计不能够完全捕获所有的问题,部分的风险被隐藏了;
难以对工作量和工作价值进行评估;
里程碑揭露问题的时间要远远落后于问题出现的时间;
这里对里程碑的方式做一些分析。我们对问题的理解往往是逐步深入的。在项目一开始的时候,业务和技术上都存在问题,存在不确定性和风险,这时候往往是最需要评估和验证的。但是里程碑方式往往要求必须深入的分析需求,很多的问题并没有得以解决,而是被悄悄的有意或无意的掩盖了。需求毕竟不是软件,它是一个不同人具有不同理解的模型,这时候,项目中各个角色对它的理解都不相同,但是这并不影响他们做出一致的决定-通过需求里程碑。问题到了设计阶段依然存在,这时候需求阶段隐藏的一些问题开始出现,导致我们不得不补充一些工作量。但是所有的问题也没有得到解决,依然存在未知的风险。那么风险到了什么时候才会暴露出来呢?最乐观的情况是在编码时期发现,最悲观的情况是在交付期发现。我们把这种过程称为固化考核过程。 问题在哪里?除了软件本身,模型也好、文档也罢,都不能够代替最后的代码。在精益原则中,我们说,必须消除浪费。当我们在开发工件的时候,我们的浪费行为已经或多或少的出现了。
与固化考核过程相对的,我们认为存在另一种动态评估过程。里程碑或是检查点并不是不重要。但是我们需要转换思路,来将里程碑的实践做的更好一些。我们上面提到说里程碑方式最大问题就在于一定要等到问题都积累起来了才解决问题,而这个时候往往已经错过了解决问题的最佳时机。而动态评估过程的含义就是在过程进行中不断的发现并解决问题,而不是等到问题累积到一定程度才批量解决。过程随着环境的变化不断的调整,以适应变化性和不确定性的需要。而里程碑实践重在提供一个复审的机会,能够从一个较高的层次上来评价软件。 这种过程就是分阶段开发软件的思路,我们也可以称呼它为迭代、螺旋、增量,都没有关系。关键在于,我们需要不断的发现导致客户不满意的问题,发现改进接电话的方法,发现改进做菜的方法,发现更快送货的方法。
实现策略
动态评估过程有一些基本的实现思路,第一个基本思路是尽可能早的发现所有的问题,如何发现呢?进行一次探险式的过程。这个过程周期不能够太长,太长的周期容易失控,而且项目初期人员未必能够全部到位;但这个周期也不能够太短,太短的周期无法发现足够数量的风险,无法为后续的过程提供丰富的数据。
有时候,我们运用原型法来实现这个Mini过程。原型法包括了需求原型和技术原型,分别用于解决业务风险和技术风险。一个典型的需求原型是建立一个界面原型,来帮助客户理解未来的软件,避免抽象的思考。我看过很多界面原型的做法,有使用HTML的,有使用画图软件的,有使用规范的XML的。但是不管如何,界面原型能够帮助用户直观的理解需求。技术原型的主要目标是解决技术风险,任何一个项目都可能存在这样或那样的技术风险。对待风险的基本态度是尽早的评估风险并制定解决方案,而不是束之高阁。技术风险的解决方案视具体情况而定,但是,值得注意的是,一个项目中,技术风险不能够过多。如果确实存在这种情况,想办法找到有经验的导师或培训师,这要比自己摸索节省许多的成本。
XP对探险式过程的评估主要包括两个方面,spike solution和迭代。spike solution其实就是我们在上面提到了的技术原型。它的目的是让不明确的评估成为明确的评估(参见XP的过程图中的Spike)。只有评估准确了,计划才能够准确。因此它是计划和迭代的输入项。
至于迭代,它是XP中的重要概念。迭代选取了用户需要的功能(称为用户故事),并进行设计、开发、测试,迭代不断重复,并解决各种各样的问题。在通过用户的测试和认可之后,最终产生了一个可以运行的版本。这个版本的产生,标志着一组迭代周期的完成。第一个小版本正是我们所强调的探险式的过程。它的成功和教训,足以让你了解项目的各种知识,包括客户的复杂组织关系,投资方的准确意图,找出所有的涉众,发现用例,令团队成员和客户达成初步的共识,验证技术方案,建立一个初步的软件架构,或是针对现有的架构进行初步的映射,程序员需要额外的培训,测试力量似乎不足够,部署环境的风险需要提前解决。只有你按照完整的生命周期真正的去做这项工作,这些问题才会在一开始都暴露出来,否则,其中的很多问题会在后续的阶段中给你制造大麻烦。 第二个基本思路是增量开发。增量和迭代有什么区别呢?Alistair Cockburn在Surviving Object-Oriented Projects一书中将增量描述为修正或改进开发过程,形象的说法是逐步的完成软件开发。注意到,XP的过程图中的小版本正是一个增量。XP认为,一个增量应该是可以发布的。做到这一点固然很好,但是并不是所有的项目都能够达成这一目标。例如,第一次的增量目标可能主要是定义一个架构,这个架构并不包含用户需要的功能,但是它是项目开发的基础。架构中可能包括业务实体基础结构、数据操纵基础架构等一系列的框架。但是对于XP来说,在用户无法发现价值的框架上花费大量的时间是不值得的,XP提倡的做法是根据需求的发展来逐步完善架构,而不是在项目一开始就花费精力开发架构。很难评价哪一种说法正确,我比较倾向于前期花费时间进行架构设计,但是实践中确实发生过设计过于复杂导致高昂成本的情况。在花费了大量的时间开发了一个属性处理框架之后,我发现其实简单属性就能够处理大部分的情况,毫无疑问,前期的设计投入打了漂。因此,重要的是权衡前期的投入时间。理想的情况是,你已经拥有了一个可重用的框架(或是架构),这样,你可以将项目的需求映射到框架上,而不是在项目一开始的时候花时间来开发框架。如果你没有框架,在项目一开始的时候,花费一定的时间来开发架构,但是这个时间不宜过长,你完全可以在后续的增量中对架构进行改进,所以不用急于一时。而且,单纯的框架(架构)开发是没有办法进行用户接受测试的,你的测试不得不推迟到第二次增量。这个理由也促使我们尽可能的缩短框架设计的周期。
而迭代则是改进或修正软件质量。这也是第三个基本思路。我们注意看XP过程图中的迭代,多次的迭代才构成一次的增量(小版本),每一次的迭代都是对上一次迭代的改进,其中可能是修正了设计错误,或是需求缺陷。值得注意的是,迭代中可能会出现新的需求变更(新需求或需求改变),并令项目人员对项目的进展速度更加的了解(Project Velocity),这些将会反过来影响计划的修正。这体现了我们在上一章所讲述的XP对待计划的态度。
并没有法律规定迭代需要和增量一起使用,但很明显,结合这两种方式是一种有效的做法。增量的目标是让项目得以向前推进(这就像是修路的时候,路的长度变长了),而迭代的目标是令软件的质量更优(就像是在一段路上架设路基、铺上水泥,建设路面设施)。这让我们想起了什么,不错,重构的两顶帽子。一顶帽子是为软件增加新功能,一顶帽子是改进软件的质量。非常的相似,只不过一个是过程级别的,一个是程序级别的。这里有一个基本的假设,不要同时增加功能和改进质量。团队也好,个人也好,一次只完成一个目标效率是最高的。
思考
和传统的先定义问题,然后再解决问题的做法不同,XP偏重于逐步的精化问题。软件开发中的问题定义和数学中不同,它往往是模糊的,动态的,需要在解决问题的过程中不断的调整解题的思路。对XP来说,这种解题思路,体现了其反馈的价值观-尽快获得客户对软件的反馈。