曾经有人向Fred Brooks请教软件项目的进度是怎样被延误的?他的回答既简单又深刻:
“某天某时。”
技术性项目(不论它是涉及水力发电厂建设,还是操作系统开发)的现实情况是:在实现大目标之前必须完成数以百计的小任务。这些任务中有些是处于主流之外的,其进度不会影响到整个项目的完成日期。而有些任务却是位于“关键路径”上,如果这些“关键”任务的进度拖后,则整个项目的完成日期就会受到威胁。
项目管理者的职责是确定所有的项目任务,建立相应的网络来描述它们之间的依赖关系,明确网络中的关键任务,然后跟踪关键任务的进展,以确保能够在“某天某时”发现进度延误情况。为了做到这一点,管理者
建议
为达到项目管理者的目标所必须完成的任务不应该以手工方式来安排,有很多优秀的项目进度安排工具可供使用。
必须建立相当详细的进度表,使得项目管理者能够监督进度,并控制整个项目。
软件项目进度安排(software project scheduling)是一种活动,它通过将工作量分配给特定的软件工程任务,从而将所估算的工作量分配到计划的项目工期内。但要注意的是,进度是随时间而不断演化的。在项目计划早期,建立的是一张宏观进度表,该进度表标识了所有主要的过程框架活动和这些活动所影响的产品功能。随着项目的进展,宏观进度表中的每个条目都会被细化成详细的进度表,这样就标识了特定的(完成一个活动所必须实现的)软件活动和任务,同时也进行了进度安排。
可以从两个不同的角度来讨论软件工程项目的进度安排。第一种情况,计算机系统的最终发布日期已经确定(而且不能更改),软件开发组织必须将工作量分布在预先确定的时间框架内。第二种情况,假定已知大致的时间界限,但是最终发布日期由软件工程开发组织自行确定,工作量是以能够最好地利用资源的方式来进行分配,而且在对软件进行仔细分析之后才决定最终发布日期。但不幸的是,第一种情况发生的频率远远高于第二种情况。
引述
过于乐观的进度安排并不会缩短实际进度,反而会拖后进度。
—— Steve McConnell
1 基本原则
就像软件工程的所有其他领域一样,软件项目进度安排也有很多的基本指导原则:
划分(compartmentalization)。必须将项目划分成多个可以管理的活动和任务。为了实现项目的划分,产品和过程都需要进行分解。
相互依赖性(interdependency)。划分后的各个活动或任务之间的相互依赖关系必须是明确的。有些任务必须按顺序出现,而有些任务则可以并发进行。有些活动只有在其他活动产生的工作产品完成后才能够开始,而有些则可以独立进行。
关键点
在进度安排时,要划分工作,描述任务间的相互依赖性,为每个任务分配工作量和时间,确定责任、输出结果和里程碑。
时间分配(time allocation)。每个要进行进度安排的任务必须分配一定数量的工作单位(例如,若干人日的工作量)。此外,还必须为每个任务指定开始日期和完成日期,任务的开始日期和完成日期取决于任务之间的相互依赖性以及工作方式是全职还是兼职。
工作量确认(effort validation)。每个项目都有预定人员数量的软件团队参与。在进行时间分配时,项目管理者必须确保在任意时段中分配的人员数量不会超过项目团队中的总人员数量。例如,某项目分配了3名软件工程师(例如,每天可分配的工作量为3人日【实际上,由于与工作无关的会议、病假、休假以及各种其他原因,可供分配的工作量要少于3人日。但在这里,我们假定员工时间是100%可用的。】)。在某一天中,需要完成7项并发的任务,每个任务需要0.5人日的工作量,在这种情况下,所分配的工作量就大于可供分配的工作量。
确定责任(defined responsibility)。进度计划安排的每个任务都应该指定特定的团队成员来负责。
明确输出结果(definedoutcome)。进度计划安排的每个任务都应该有一个明确的输出结果。对于软件项目而言,输出结果通常是一个工作产品(例如,一个模块的设计)或某个工作产品的一部分。通常可将多个工作产品组合成可交付产品。
确定里程碑(defined milestone)。每个任务或任务组都应该与一个项目里程碑相关联。当一个或多个工作产品经过质量评审(第15章)并且得到认可时,就标志着一个里程碑的完成。
随着项目进度的推进,会应用到上述的每一条原则。
2 人员与工作量之间的关系
许多负责软件开发工作的管理者仍然普遍坚信这样一个神话:“即使进度拖后,我们也总是可以在项目后期增加更多的程序员来跟上进度。”不幸的是,在项目后期增加人手通常会对项目产生破坏性的影响,其结果是使进度进一步拖延。后期增加的人员必须学习这一系统,而培训他们的人员正是那些一直在工作着的人,当他们进行教学时,就不能完成任何工作,从而使项目进一步延后。
建议
如果必须给一个已经拖延的项目增加人员,就要确保已将详细划分的任务分配给他们。
除去学习系统所需的时间之外,整个项目中,新加入人员将会增加人员之间交流的路径数量和交流的复杂度。虽然交流对于一个成功的软件开发项目而言绝对是必不可少的,但是每增加一条新的交流路径就会增加额外的工作量,从而需要更多的时间。
多年以来的经验数据和理论分析都表明项目进度是具有弹性的。即在一定程度上可以缩短项目交付日期(通过增加额外资源),也可以拖延项目交付日期(通过减少资源数量)。
PNR ( Putnam-Norden-Rayleigh)曲线表明了一个软件项目中所投入的工作量与交付时间的关系。项目工作量和交付时间的函数关系曲线如图所示。图中的t。表示项目最低交付成本所需的最少时间(即花费工作量最少的项目交付时间),而t。左边(即当我们想提前交付时)的曲线是非线性上升的。
关键点
PNR曲线表明,拖延项目交付时间可以显著地降低项目成本。
举一个例子,假设一个软件项目团队根据进度安排和现有的人员配置,估算所需要的工作量应为E。,正常的交付时间应为t。虽然可以提前交付,但曲线在t的左侧急剧上升。事实上,PNR曲线不仅说明了项目的交付时间不能少于0.75t,如果想更少,项目会进入“不可能的区域”,并面临着很高的失败风险;还说明了最低成本的交付时间t。应该满足t。=2t,即拖延项目交付可以明显降低成本,当然,这里的成本必须将与延期相关的营销成本排除在外。
软件方程[Put92]就是来源于PNR曲线,它表明了完成一个项目的时间与投入该项目的人员工作量之间是高度非线性的关系。交付的代码(源程序代码)行数L与工作量和开发时间的关系可以用下面的公式表示:
其中,E是以人月为单位的开发工作量;P是生产率参数,它反映了影响高质量软件工程工作的各种因素的综合效果(P通常在2000到12000 之间取值);t是以月为单位的项目工期。
重新调整这个软件方程,可以得到开发工作量E的计算公式:
建议
离项目的交付日期越来越近时,你意识到,不管参与工作的人数是多少,工作均不能按计划完成。那就面对现实,确定新的交付日期。
其中,E是在软件开发和维护的整个生命周期内所需的工作量(按人年计算);t是以年为单位的开发时间;引入平均劳动力价格因素($/人年)之后,开发工作量的计算公式还能够与开发成本相关联。
这一方程式引出了一些有趣的结果。假设有一个复杂的实时软件项目,估计需要33000源代码行和12人年的工作量。如果项目团队有8个人,那么项目大约需要1.3年的时间完成。但是如果将交付日期延长到1.75年,则由上式所描述的模型所具有的高度非线性特性将得出以下结论:
这意味着通过将交付日期推迟6个月,我们可以将项目团队的人数从8人减少到4人!这一结果的有效性有待考证,但是其含意却十分清楚:通过在略为延长的时间内使用较少的人员,可以实现同样的目标。
3 工作量分配
各种软件项目估算技术最终都归结为对完成软件开发所需工作单位(如人月)的估算。软件过程中的工作量分配通常采用40-20-40法则。总体工作量的40%分配给前期的分析和设计,40%用于后
期测试。因此,你可以推断出编码工作(20%的工作量)是次要的。
提问
在软件过程的工作流程中应如何分配工作量?
这种工作量分配方法只能作为指导原则【现在,40-20-40法则不再适用。有些人认为用于分析和设计的工作量应超过总工作量的40%。而相反的是,敏捷开发的倡导者(第5章)认为“前期”工作应该越快越好,团队应该快速进入构建阶段】。各个项目的特点决定了其工作量如何分配。用于项目计划的工作量很少超过2%~3%,除非提交给组织的项目计划费用极高而且具有高风险。客户交流与需求分析大约占用10%~25%的项目工作量,用于分析或原型开发的工作量应该与项目规模和复杂度成正比地增长。通常有20%~25%的工作量用于软件设计,用于设计评审和随之而来的迭代开发也必须考虑。
因为在软件设计时投入了相当的工作量,所以随后的编码工作就变得相对简单。总体工作量的15%~20%就可以完成这一工作。测试和随之而来的调试工作将占用30%~40%的软件开发工作量。软件的重要性决定了所需测试工作的分量,如果软件系统是人命关天的(即软件错误可能使人丧命),就应该考虑分配更高的测试工作量比例。
3 为软件项目定义任务集
无论选择哪一种过程模型,一个软件团队要完成的工作都是由任务集组成的,这些任务集使得软件团队能够定义、开发和最终维护计算机软件。没有能普遍适用于所有软件项目的任务集。适用于大型复杂系统的任务集可能对于相对简单的小型软件项目而言就过于复杂。因此,有效的软件过程应该定义一组任务集来满足不同类型项目的要求。
任务集中包含了为完成某个特定项目所必须完成的所有软件工程工作任务、里程碑、工作产品以及质量保证过滤器。为了获得高质量的软件产品,任务集必须提供充分的规程要求,但同时又不能让项目团队负担不必要的工作。
在进行项目进度安排时,必须将任务集分布在项目时序图上。任务集应该根据软件团队所决定的项目类型和严格程度而有所不同。尽管很难建立一个全面详尽的软件项目分类方法,但是大多数软件组织遇到的项目一般属于下述类型:
1.概念开发项目(concept development project)。目的是为了探索某些新的业务概念或者某种新技术的应用。
2.新应用开发(new application development)项目。根据特定的客户需求而承担的项目。
3.应用增强(application enhancement)项目。对现有软件中最终用户可见的功能、性能或界面进行修改。
4.应用维护项目(application maintenance project)。以一种最终用户不会立即察觉到的方式对现有软件进行纠错、修改或者扩展。
5.再工程项目(reengineering project)。为了全部或部分重建一个现有(遗留)系统而承担的项目。
即使在单一的项目类型中,也会有许多因素影响任务集的选择。[Pre05]中描述了很多因素:项目的规模、潜在的用户数量、任务的关键性、应用程序的寿命、需求的稳定性、客户/开发者进行沟通的容易程度、可应用技术的成熟度、性能约束、嵌入式和非嵌入式特性、项目人员配置以及再工程因素等。综合考虑这些因素就形成了严格程度(degree of rigor)的指标,它将应用于所采用的软件过程中。
网络资源
适应性过程模型(Adapta-ble Process Model,APM)可以辅助不同的软件项目定义各自的任务集。有关APM的详细信息见www.rspa.com/apm。