软件开发基本原则(四)—— 风险管理
1988年,Peat Marwick针对600家成功公司的调查结果显示,35%的公司有过软件项目失控的经历。(Rothfeder 1988)
1982年,Allstate公司宣布其公司运营全部要实行自动化。他们启动了一个将耗时5年投资800万美元的大型项目,而在花费了6年和1500万美元后,Allstate公司重新调整了目标和最终期限,重新调整后的预算大约1亿美元。
1988年,Westpac Banking公司决定重新设计他们的信息系统。他们做了5年、8500万美元的计划。3年后,在花费了1.5亿美元却依然收效甚微时,Westpac Banking公司为了减少损失,取消了这个项目,并为此裁员500人。(Glass 1992)
从项目管理的角度来看,有五大硬性知识领域:范围管理、进度管理、成本管理、质量管理和风险管理。风险会出现在前面四个领域的各个过程中,只有有效地消除可能发生的危险因素,才能确保项目顺利推进。项目的风险贯穿于整个项目过程,因此整个项目的生命周期都应该坚持有效的风险管理。
根据风险的内容,可以把风险归为以下几类:
- 产品规模风险:与软件的总体规模相关的风险
- 商业影响风险:商业风险影响到软件开发的生存能力
- 客户特性风险:与客户的素质以及开发者和客户沟通能力相关的风险
- 过程定义风险:与软件过程定义相关的风险
- 开发环境风险:与开发工具的可用性及质量相关的风险
- 技术风险:技术风险是指在设计、实现、接口、验证、维护、规约的二义性、技术的不确定性、陈旧的技术等方面存在的风险
- 人员数目及经验带来的风险:与参与工作的软件工程师的总体技术水平及项目经验相关的风险
软件项目的风险主要体现在四个方面:需求、技术、成本、进度。风险管理是一个相当重要的话题,但涉及的问题太多,很难在本章中全部囊括,本章主要讲述进度相关的风险管理。
风险管理要素
软件风险管理就是在风险成为影响软件项目成功的威胁之前,识别、处理并消除风险。可以在几个层次上定位风险管理:
1、危机管理 — 救火模式,即在风险已经造成麻烦后才着手处理它们
2、失败处理 — 觉察到了风险并迅速做出反应,但只是在风险发生之后
3、风险环节 — 事先制定好风险发生后的补救措施,但不做任何防范措施
4、着力预防 — 将风险识别与风险防范作为软件项目的一部分加以规划和执行
5、消灭根源 — 识别和消除可能发生的风险的根源
本章描述如何定位第4、5个层面上的进度风险管理。
总体来讲,风险管理由风险评估和风险控制组成:
图 5.1-1 风险管理由风险评估和风险控制组成
1. 风险评估
- 风险识别:建立一个潜在破坏项目进度的风险列表
- 风险分析:评估每一个风险出现可能性及其影响,判定风险的级别
- 风险优先级:按风险影响大小排出一个风险优先级列表,这个列表将作为风险控制的基础
- 风险管理计划:定制一个应对每个重要风险的方案,同时应确保每一个单独的风险管理计划相互之间以及与项目计划之间保持一致
- 风险化解:执行每一个重要风险所对应管理计划
- 风险监控:对解决风险的过程进行监控。还包括:识别新的风险,并将其加入到正在进行的风险管理进程;在风险列表中移除已经化解的风险等工作
风险识别
1. 最常见的进度计划风险
- 功能蔓延
- 需求镀金或开发人员镀金
- 质量不稳定
- 计划过于乐观
- 设计欠佳
- 银弹综合症
- 研究导向的开发
- 人员薄弱
- 承包人导致的失败
- 开发人员与客户之间发生摩擦
2. 进度计划风险列表
下面列出了详尽的可能对软件进度有负面影响的潜在风险。除了这里所列出的风险,大多数项目都有其特定的风险,如:
“Joe要退出项目组,除非可以允许他带自己的小狗来上班,而管理层还没有决定是否同意他这样做”—— 这样的风险就要靠自己识别了!
潜在的进度计划风险: (资料来源:Gilb 1988、Boehm 1989 Pressman 1993、Thomsett 1993、Jones 1994)
类型 |
风险 |
1、计划编制 |
1) 计划、资源和产品定义全凭客户或上层领导口头指令,而且不完全一致 2) 计划是优化的,是“最佳状态”(但不现实,只能算是“期望状态”) 3) 计划忽略了必要的任务 4) 计划基于使用特定的小组成员,而那个小组成员其实指望不上 5) 在限定时间内无法建成已定规模大小的产品 6) 产品规模比估计的要打(代码行数、功能点或与前一产品规模的百分比) 7) 工作量大于估计数(代码行数、功能点、模块等) 8) 进度已经拖延的项目在重新评估时过于优化或忽略项目历史 9) 过度的进度压力造成生产力下降 10) 目标日期提前,但没有相应地调整产品范围或可用资源 11) 一个任务的延时导致相关任务的连锁反应 12) 涉足不熟识的产品领域,花费在设计和实现上的时间比预期要多 |
2、组织和管理 |
1) 项目缺乏一个用凝聚力的最高领导人 2) 由于前期乏力,项目长时间被搁置 3) 解雇和削减开支导致项目小组能力下降 4) 仅由管理层或市场人员进行技术决策,导致计划进度延长 5) 低效的项目组织结构降低生产率 6) 管理层审查或决策的周期比预期的时间长 7) 预算削减打乱项目计划 8) 管理层作出了打击项目组积极性的决定 9) 非技术的第三方的工作比预期延长(预算批准、设备采购、法律审查等) 10) 计划性太差,无法达到期望的开发速度 11) 项目计划由于压力而放弃,导致开发混乱低效 12) 管理层强调英雄主义而忽略客观确切的状态报告,错过发现和改正问题的机会 |
3、开发环境 |
1) 设施没有及时到位 2) 设施到位但不配套 3) 设施拥挤、杂乱或破损 4) 开发工具没能及时到位 5) 开发工具不如期望的那样有效 6) 开发工具的选择不是基于技术需求,不能提供计划要求的性能 7) 开发人员需要长时间创建工作环境或切换新开发工具 8) 新开发工具的学习周期比预期的长,内容繁多 |
4、最终用户 |
1) 最终用户坚持新的需求 2) 最终用户对于最后交付的产品不满意,要求重新设计或重做 3) 最终用户不买进项目产品,无法提供后续支持 4) 最终用户的意见未被采纳,造成产品无法满足最终用户的期望而必须重做 |
5、客户 |
1) 客户坚持新的需求 2) 客户对规则、原型和规格的审核和决策周期比预期的长 3) 客户没有或不能参与规划和原型审查工作,导致需求不稳定和耗时的变更 4) 客户沟通或答复的时间比预期长 5) 客户坚持技术决策而导致进度计划延长 6) 客户对开发进度管理过细,导致实际进展缓慢 7) 客户提供的组件无法与开发的产品匹配,导致额外的设计和集成工作 8) 客户提供的组件质量欠佳,导致额外的设计、测试、集成和客户关系管理工作 9) 客户要求的支持工具和环境不兼容、性能差或功能不完善,导致生产率降低 10) 客户不接受交付的软件,尽管它满足合同的条款要求 11) 客户期望的开发速度无法达到 |
6、承包商 |
1) 承包商没有按承诺交付组件 2) 承包商递交的组件质量低下无法满足要求,必须再花时间改进 3) 承包商没有买进项目开发需要的工具,进而无法提供需要的性能水平 |
7、需求 |
1) 需求已经成为项目的基准,但变化仍在继续 2) 需求定义欠佳,但进一步的定义会扩展项目的范畴 3) 添加额外的需求 4) 需求定义含糊的部分需要的处理时间比预期多 |
8、产品 |
1) 错误发生率高的模块需要比预期更多的设计、实现和测试工作 2) 校正质量低下的产品需要比预期更多的设计、实现和测试工作 3) 在一个或多个新兴领域推过产品技术使得进度延长或不可预期 4) 由于软件的功能错误使得需要重新设计和实现 5) 开发额外不需要的功能(镀金)延长了计划进度 6) 要满足产品规模的要求,需要比预期长的时间,包括重新计划、设计和实现 7) 严格要求与原有系统兼容,需要进行比预期更多的计划、设计、实现和测试 8) 要与不受项目组控制的其他系统集成,导致无法预料的设计、实现和测试工作 9) 要求在不同操作系统或软硬件环境下运行将花费比预期更长的时间 10) 在不熟识或未经检验的软件环境中运行,产生未预料到的问题 11) 在不熟识或未经检验的硬件环境中运行,产生未预料到的问题 12) 开发一些全新的功能模块比预期花费更长时间 13) 依赖未成熟的技术,使得进度延长或不可预期 |
9、外部环境 |
1) 产品依赖政府的政策或制度,而政策或制度不可预期 2) 产品依赖草拟中的技术标准,而最后的标准不可预期 |
10、人员 |
1) 招聘人员所花时间比预期长 2) 培训、工作许可证或其他项目的收尾等作为先决条件的任务不能按时完成 3) 开发人员和管理层之间关系不佳导致决策缓慢影响进度 4) 项目组成员没有全身心投入项目,进而无法达到要求的产品质量水平 5) 缺乏激励措施,士气低下,降低生产力 6) 缺乏必要的规范,增加了工作失误几率和重复工作 7) 某些人需要更多时间适应新的软件工具和环境 8) 某些人需要更多时间适应新的硬件工具和环境 9) 项目结束前,成员调离团队或离职 10) 项目后期加入新开发人员,额外的培训和沟通降低现有成员的生产率 11) 项目成员不能有效地一起工作 12) 项目组成员间有冲突,导致沟通不畅、设计欠佳、接口错误和额外的重复工作 13) 有问题的成员没有调离项目组,损害了其他成员的积极性 14) 项目的最佳人选没有加入项目组 15) 项目的最佳人选已加入项目组,但因政治或其它原因未能合理使用 16) 没有找到项目急需的,具有特殊技能的人 17) 关键人物只能兼职参与 18) 项目人员不足 19) 任务的分配与人员技能不匹配 20) 人员工作的进度比预期的慢 21) 项目管理人员怠工导致计划的进度失效 22) 技术人员怠工导致工作遗漏和质量低下 |
11、设计和实现 |
1) 设计过于简单,无法确定主要事件,并导致重新设计和实现 2) 设计过于复杂,导致一些不必要的工作,影响实现效率 3) 设计质量低下,导致重复设计和实现 4) 使用不熟识的方法和技术,导致额外的培训时间 5) 使用低级语言开发产品,导致生产率比预期低 6) 一些必要的功能无法使用现有的代码或库实现,必须采用新库或重新实现 7) 代码和库质量低下导致需要额外的测试、错误修正或重做 8) 过高估计了工具对计划进度的节省量 9) 独立开发的模块无法有效集成,需要重新设计或重做 |
12、过程 |
1) 大量的书面工作导致进度比预期慢 2) 进度跟踪不准确,导致无法预知项目是否已落后于计划进度 3) 前期的质量保证行为不真实,导致后期重复工作 4) 质量跟踪不准确,导致无法得知影响进度的质量问题 5) 不够正规(缺乏对软件开发标准和策略的遵循),导致沟通不足和质量问题 6) 过于正规(教条地遵循软件开发标准和策略),导致过多耗时于无用的工作 7) 向管理层撰写进度报告占用开发人员的时间比预期多 8) 风险管理不够重视,导致没有发现重大的项目风险 9) 软件项目风险管理花费的时间比预期多 |
风险分析
1. 风险暴露量
一种很有用的风险分析方法就是风险暴露量。风险暴露量就是风险发生的概率乘以损失的程度。举例来说:如果你认为“完成需求分析比原计划延长4周的概率是30%”,那么风险暴露量就是4周*30%=1.2周。
风 险 |
发生概率 |
损失程度(周) |
风险暴露量(周) |
计划过于乐观 |
50% |
5 |
2.5 |
由于要完全支持自动从主机更新数据而造成的额外需求 |
5% |
20 |
1.0 |
由于市场变化而增加额外的功能 |
35% |
8 |
2.8 |
图形格式子系统接口不稳定 |
25% |
4 |
1.0 |
设计欠佳——需要重新设计 |
15% |
15 |
2.25 |
项目审批超过预计时间 |
25% |
4 |
1.0 |
设施未能及时到位 |
10% |
2 |
0.2 |
为管理层撰写进程报告占用开发人员的时间比预期的多 |
10% |
1 |
0.1 |
承包商的图形格式子系统推迟交付 |
10~20% |
4 |
0.4~0.8 |
新的编程工具没有节省预期的时间 |
30% |
5 |
1.5 |
表 5.3.1-1 风险暴露量
1) 评估损失程度
损失程度常常比发生概率更容易估算,在表5.3.1-1中,完全可能很精确地估计出由于增加“完全支持自动从主机更新数据”而增加的研发时间是20个月。如果有时损失程度不容易直接估算出来,还可以把损失分解为更小的部分分别进行估算,之后将各个小的独立评估结果累加得出合计估算值。
2) 评估发生概率
估算发生概率比估算损失程度更具主观性。有许多实践方法可以提高主观评估的精确度,例如:
- 由最熟识系统的人评估每个风险的发生概率,然后保留一份风险评估审核文件
- 每个人对风险进行独立评估,然后讨论评估的合理性,直到达成共识
- 使用“形容词标准”,如非常可能、很可能、可能、或许、不大可能和不可能等,然后把口头评估转换成量化的评估
2. 项目的延期和缓冲
由于我们只谈论进度风险,所以可以累加所有的风险暴露量来得到项目总风险暴露量。这个项目的总风险暴露量为12.8~13.2周,这意味着,如果不做任何风险管理的话计划可能要延期12.8~13.2周。如果例子中的项目历时25周,那么超出预计值12.8~13.2周就很显然要进行风险管理了。
风险优先级
项目通常花费80%的金钱解决20%的问题,所以风险管理的重点是关注那最重要的20%的部分。(Boehm 1989)
如果只关注进度计划风险而不是关注所有的风险,确定风险优先级的工作就变得比较容易了。在风险评估表中按风险暴露量从大到小排序看看会得到什么结果:
序 号 |
风 险 |
发生概率 |
损失程度(周) |
风险暴露量(周) |
1 |
由于市场变化而增加额外的功能 |
35% |
8 |
2.8 |
2 |
计划过于乐观 |
50% |
5 |
2.5 |
3 |
设计欠佳——需要重新设计 |
15% |
15 |
2.25 |
4 |
新的编程工具没有节省预期的时间 |
30% |
5 |
1.5 |
5 |
图形格式子系统接口不稳定 |
25% |
4 |
1.0 |
6 |
由于要完全支持自动从主机更新数据而造成的额外需求 |
5% |
20 |
1.0 |
7 |
项目审批超过预计时间 |
25% |
4 |
1.0 |
8 |
承包商的图形格式子系统推迟交付 |
10~20% |
4 |
0.4~0.8 |
9 |
设施未能及时到位 |
10% |
2 |
0.2 |
10 |
为管理层撰写进程报告占用开发人员的时间比预期的多 |
10% |
1 |
0.1 |
表 5.4-1 排序后的风险暴露量
排序后的风险评估表实际上就形成了一个粗略的风险优先级列表。如果能成功地处理风险列表中的前5个风险,就有希望将超出预期计划的时间减少10.05周,如果能成功地处理后5个风险,则只能将超出预期计划的时间减少2.7~3.1周。一般情况下,你的时间最好花在风险列表中靠前的风险上。
表5.4-1的排序只是粗略的,你可能想将损失更大的风险排在优先级更高的位置,确保他们不会发生(如:上表第6个风险)。
你也可以把一些关联的风险排在比各自优先级更高的位置,如表5.4-1中第5和第8个风险。让承包商开发图形格式子系统接口,其组合风险要远大于它们各自的风险。
这里确定的风险优先级是比较粗糙的,因为用于确定风险的数据都是估计的,因此优先级本身也就是个相对主观的值。所以,对风险的客观公正态度,是风险管理必要的组成部分。
风险管理计划
编制风险管理计划的重点是制定一个计划,以处理风险分析中确定的高优先级风险。风险管理计划可以简单地理解为一段一段的风险管理描述,如:每个风险的起因,表现形式,可能发生的时间、地点,为什么发生以及怎样发生等。风险管理计划同时也包含:监控风险,处理新风险,关闭已化解的风险等计划内容。
风险化解
特定风险的化解在许多情况下都决定于特定风险本身,下面列出一些化解风险的一般方法:
1、 避免风险
不要做冒险的活动。例如,你的项目进度比较紧,有一个工具提供商声称它的工具能提高你的开发速度,但是你的团队成员从来没使用过这个工具,这时你就不应该冒险采用这个工具。首先该工具不一定像它声称的那样好,其次对工具的学习和熟识需要一个过程,如果冒险用它很可能会得不偿失。
2、 转移风险
有时,项目某部分的风险对项目另一部分来说却不是风险,因此可以将它转移到另一部分。例如,可以负责大部分的系统设计工作,但不要承担不熟识的部分的设计工作,让比较有把握的人负责设计这部分。
3、 购买风险相关信息
如果不能确切知道风险的严重性,可以做一些调研。也可以请外面的咨询顾问帮你进行评估。
4、 消除产生风险的根源
例如,系统中某部分的设计可能面临严重的问题,可将其作为一个研究项目彻底重新设计。
5、 接受风险
如果风险的后果较小,而处理它的成本太高,那么可以接受这个风险,不做任何处理。
6、 发布风险
让上级领导、市场人员、客户知道有关的风险以及可能的后果。这样,即使风险真的发生了,他们也不会感到太惊讶。
7、 控制风险
定制计划应对风险无法化解的情形。例如分配额外的资源来测试设计中令人担心的那部分系统,并留出额外时间处理测试发现的问题。
8、 记住风险
总结项目相关的风险及其处理办法、处理效果等,为未来的项目建立一组风险管理计划。
风险 |
控制方法 |
1、功能蔓延 |
a) 使用基于用户的实践 b) 使用增量开发实践 c) 控制功能集 d) 采取针对变更的设计 |
2、需求镀金或开发人员镀金 |
a) 修正需求 b) 时间锁定开发 c) 控制功能集 d) 使用舍弃原型实践 e) 基于进度表的开发 |
3、质量低劣 |
a) 给QA留出时间,注重质量保证基础 |
4、计划过于乐观 |
a) 采用多估算实践 b) 多个估算员和自动估算工具有原则地进行谈判 c) 基于进度表的开发 d) 使用增量开发实践 |
5、设计低劣 |
a) 要有清晰的设计活动和足够的设计时间 b) 进行设计检查 |
6、银弹综合症 |
a) 要有一定的生成率要求 b) 建立软件量度计划 c) 建立软件工具库 |
7、研究导向的开发 |
a) 不要试图进行研究的同时强调加快开发速度 b) 使用基于风险的生命周期模型警惕地进行风险管理 |
8、人员薄弱 |
a) 招募顶尖人才 b) 项目开始前招聘或预定关键成员 c) 培训 d) 团队建设 |
9、承包商失败 |
a) 检查参考资料 b) 外包前分析承包商能力 c) 积极管理承包商 |
10、开发人员与客户发生摩擦 |
a) 采用面向进度的实践 |
表 5.6-1 常见进度计划风险的控制方法
风险监控
由于风险在项目推进过程中会增强或减弱,所以需要对风险进行监控,检查每个风险的化解程度,关闭完全化解的风险,添加新产生的风险。
1、 前十风险列表
最有效的风险监控手段之一就是建立前十风险列表,该表包含每个风险当前的级别、以前的级别、已经上表的次数和上次审核后风险化解的步骤等。
前十风险列表最有意义的方面是促使你定期查看和思考这些风险,并对重要的变化给予警告。
前十风险列表的示例:
表 5.7-1 前十风险列表
2、 中间检查
虽然前十风险列表可能是最有效的风险监控手段,但每个项目也应该包括中间过程检查。在完成每个主要里程碑后进行一次小规模的检查是非常有益的实践。
3、 风险官员
有时任命风险官员很有用,风险官员的职责就是对项目风险提出警告,防止项目经理和开发人员忽视计划中的风险管理。