第13章 软件项目管理 Software Project Management 13.1 估算软件规模(Software scale Estimation) 13.2 工作量估算(Empirical Estimation Models) 13.3 进度计划(Schedule Planning) 13.4 人员组织(Personnel Organization) 13.5 质量保证(Quality Assurance)
(Software Configuration Management) 13.7 能力成熟度模型 13.8 小结 习题 13.6 软件配置管理 (Software Configuration Management) 13.7 能力成熟度模型 (Capability Maturity Model) 13.8 小结 习题
13.1 估算软件规模(Software scale Estimation) 13.1.1 代码行技术(Lines of Code) 由多名有经验的软件工程师分别做出估计。每个人都估计程序的最小规模(a)、最大规模(b)和最可能的规模(m),分别算出这3种规模的平均值,和之后,再用下式计算程序规模的估计值: L= (13.1) 用代码行技术估算软件规模时,当程序较小时常用的单位是代码行数(LOC),当程序较大时常用的单位是千行代码数(KLOC)。
13.1.2 功能点技术(Function Point) 功能点技术依据对软件信息域特性和软件复杂性的评估结果,估算软件规模。这种方法用功能点(FP)为单位度量软件规模。 1. 信息域特性 功能点技术定义了信息域的5个特性,分别是输入项数(Inp)、输出项数(Out)、查询数(Inq)、主文件数(Maf)和外部接口数(Inf)。
2. 估算功能点的步骤 (1) 计算未调整的功能点数UFP 把产品信息域的每个特性(即Inp、Out、Inq、Maf和Inf)都分类为简单级、平均级或复杂级,并根据其等级为每个特性分配一个功能点数(例如,一个简单级的输入项分配3个功能点,一个平均级的输入项分配4个功能点,而一个复杂级的输入项分配6个功能点)。 然后,用下式计算未调整的功能点数UFP: UFP=a1×Inp+a2×Out+a3×Inq+a4×Maf+a5×Inf 其中,ai(1≤i≤5)是信息域特性系数,其值由相应特性的复杂级别决定,如表13.1(见书297页)所示。
(2) 计算技术复杂性因子TCF 这一步骤度量14种技术因素对软件规模的影响程度。用下式计算技术因素对软件规模的综合影响程度DI: DI=
技术复杂性因子TCF由下式计算: TCF=0.65+0.01×DI 因为DI的值在0~70之间,所以TCF的值在0.65~1.35之间。 (3) 计算功能点数FP 用下式计算功能点数FP: FP=UFP×TCF 在判断信息域特性复杂级别和技术因素的影响程度时,存在着相当大的主观因素。
这类模型的形式: E=A+B×(ev)C A、B和C是由经验数据导出的常数, E是以人月为单位的工作量, ev是估算变量(KLOC或FP)。 13.2 工作量估算(Empirical Estimation Models) 13.2.1 静态单变量模型(Static Single-Variable Models) 这类模型的形式: E=A+B×(ev)C A、B和C是由经验数据导出的常数, E是以人月为单位的工作量, ev是估算变量(KLOC或FP)。
13.2.2 动态多变量模型(Dynamic Multivariable Models) 把工作量看作是软件规模和开发时间这两个变量的函数(软件方程式)。 动态多变量估算模型的形式: E=(LOC×B0.333/P)3×(1/t)4 (13.2) E是以人月或人年为单位的工作量; t是以月或年为单位的项目持续时间; B是特殊技术因子,它随着对测试、质量保证、文档及管理技术的需求的增加而缓慢增加,对于较小的程序(KLOC=5~15),B=0.16,对于超过70 KLOC的程序,B=0.39; P是生产率参数,它反映了对工作量的影响因素.
COCOMO是构造性成本模型(constructive cost model)的英文缩写。它反映了十多年来在成本估计方面所积累的经验。
COCOMO2给出了3个层次的软件开发工作量估算模型,它对软件细节考虑的详尽程度逐级增加,既可以用于不同类型的项目,也可以用于同一个项目的不同开发阶段。这3个层次的估算模型分别是: (1) 应用系统组成模型。这个模型主要用于估算构建原型的工作量,模型名字暗示在构建原型时大量使用已有的构件。 (2) 早期设计模型。这个模型适用于体系结构设计阶段。 (3) 后体系结构模型。这个模型适用于完成体系结构设计之后的软件开发阶段。
下面以后体系结构模型为例,介绍COCOMO2模型。该模型把软件开发工作量表示成代码行数(KLOC)的非线性函数: E= (13.3) 其中, E是开发工作量(以人月为单位), a是模型系数, KLOC是估计的源代码行数(以千行为单位), b是模型指数, fi(i=1~17)是成本因素。
(1) 新增加了4个成本因素,它们分别是要求的可重用性、需要的文档量、人员连续性(即人员稳定程度)和多地点开发。这个变化表明,这些因素对开发成本的影响日益增加。 (2) 略去了原始模型中的2个成本因素(计算机切换时间和使用现代程序设计实践)。现在,开发人员普遍使用工作站开发软件,批处理的切换时间已经不再是问题。而“现代程序设计实践”已经发展成内容更广泛的“成熟的软件工程实践”的概念,并且在COCOMO2工作量方程的指数b中考虑了这个因素的影响。
(3) 某些成本因素(分析员能力、平台经验、语言和工具经验)对生产率的影响(即工作量系数最大值与最小值的比率)增加了,另一些成本因素(程序员能力)的影响减小了。 为了确定工作量方程中模型指数b的值,原始的COCOMO模型把软件开发项目划分成组织式、半独立式和嵌入式这样3种类型,并指定每种项目类型所对应的b值 b= (13.4) 因此,b的取值范围为1.01~1.26。显然,这种分级模式比原始COCOMO模型的分级模式更精细、更灵活。
COCOMO2使用的5个分级因素如下所述: (1) 项目先例性。 (2) 开发灵活性。 (3) 风险排除度。 (4) 项目组凝聚力。 (5) 过程成熟度。
13. 3 进度计划(Schedule Planning) 13. 3 13.3 进度计划(Schedule Planning) 13.3.1 估算开发时间(Development Time Estimation) 估算出完成给定项目所需的总工作量之后,接下来需要回答的问题就是: 用多长时间才能完成该项目的开发工作? 对于一个估计工作量为20人月的项目,可能想出下列几种进度表: 1个人用20个月完成该项目; 4个人用5个月完成该项目; 20个人用1个月完成该项目。 但是,这些进度表并不现实,实际上软件开发时间与从事开发工作的人数之间并不是简单的反比关系。
通常,成本估算模型也同时提供了估算开发时间T的方程。例如: (1) Walston_Felix模型 T=2.5E0.35 (2) 原始的COCOMO模型 T=2.5E0.38 (3) COCOMO2模型 T=3.0E0.33+0.2×(b-1.01) (4) Putnam模型 T=2.4E1/3 E是开发工作量(以人月为单位), T是开发时间(以月为单位)。
开发时间与从事开发工作的人数并不成反比关系。出现这种现象主要有下述两个原因: 当小组变得更大时,每个人需要用更多时间与组内其他成员讨论问题、协调工作,因此增加了通信开销。 如果在开发过程中增加小组人员,则最初一段时间内项目组总生产率不仅不会提高反而会下降。
13.3.2 Gantt图(Gantt Diagram) 假设有一座陈旧的矩形(宽、长)木板房需要重新油漆。这项工作必须分3步完成: 首先刮掉旧漆(2、4),然后刷上新漆(3、6),最后清除(1、2)溅在窗户上的油漆。假设一共分配了15名工人去完成这项工作,然而工具却很有限: 只有5把刮旧漆用的刮板,5把刷漆用的刷子,5把清除溅在窗户上的油漆用的小刮刀。怎样安排才能使工作进行得更有效呢?
图13.1 旧木板房刷漆工程的Gantt图
13.3.3 工程网络(Project Net) Gantt图也有3个主要缺点: (1) 不能显式地描绘各项作业彼此间的依赖关系; (2) 进度计划的关键部分不明确,难于判定哪些部分应当是主攻和主控的对象; (3) 计划中有潜力的部分及潜力的大小不明确,往往造成潜力的浪费。
在工程网络中用箭头表示作业(例如,刮旧漆,刷新漆,清理等),用圆圈表示事件(一项作业开始或结束)。注意,事件仅仅是可以明确定义的时间点,它并不消耗时间和资源。作业通常既消耗资源又需要持续一定时间。图13.2是旧木板房刷漆工程的工程网络。图中表示刮第1面墙上旧漆的作业开始于事件1,结束于事件2。用开始事件和结束事件的编号标识一个作业,因此“刮第1面墙上旧漆”是作业1—2。
图13.2 旧木板房刷漆工程的工程网络 只有第1面墙上的旧漆刮完之后,才能开始刮第2面墙上旧漆和给第1面墙刷新漆这两个作业。因此,工程网络显式地表示了作业之间的依赖关系。 虚线箭头,它们表示虚拟作业,也就是事实上并不存在的作业。引入虚拟作业是为了显式地表示作业之间的依赖关系。 例如,事件4既是给第1面墙刷新漆结束,而且第2面墙上的旧漆也必须已经刮净(事件3)。在事件3和事件4之间有依赖关系,虚拟作业3—4明确地表示了这种依赖关系。注意,虚拟作业既不消耗资源也不需要时间。
13.3.4 估算工程进度(Schedule Estimation) 画出类似图13.2那样的工程网络之后,系统分析员就可以借助它的帮助估算工程进度了。为此需要在工程网络上增加一些必要的信息。 首先,把每个作业估计需要使用的时间写在表示该项作业的箭头上方。注意,箭头长度和它代表的作业持续时间没有关系,箭头仅表示依赖关系,它上方的数字才表示作业的持续时间。
图13.3 旧木板房刷漆工程的完整的工程网络
13.3.5 关键路径(Key Path) 图13.3中有几个事件的最早时刻和最迟时刻相同,这些事件定义了关键路径,在图中关键路径用粗线箭头表示。关键路径上的事件(关键事件)必须准时发生,组成关键路径的作业(关键作业)的实际持续时间不能超过估计的持续时间,否则工程就不能准时结束。 工程项目的管理人员应该密切注视关键作业的进展情况,如果关键事件出现的时间比预计的时间晚,则会使最终完成项目的时间拖后;如果希望缩短工期,只有往关键作业中增加资源才会有效果。
13.3.6 机动时间(Flexible Time) 机动时间=(LET)结束-(EET)开始-持续时间 对于前述油漆旧木板房的例子,计算得到的非关键作业的机动时间列在表13.6(见书308页)中。
图13.4 旧木板房刷漆工程改进的Gantt图之一
这个简单例子明显说明了工程网络比Gantt图优越的地方: 它显式地定义事件及作业之间的依赖关系,Gantt图只能隐含地表示这种关系。但是Gantt图的形式比工程网络更简单更直观,为更多的人所熟悉,因此,应该同时使用这两种工具制订和管理进度计划,使它们互相补充取长补短。
13.4 人员组织(Personnel Organization) 软件项目成功的关键是有高素质的软件开发人员。然而大多数软件的规模都很大,单个软件开发人员无法在给定期限内完成开发工作,因此,必须把多名软件开发人员合理地组织起来,使他们有效地分工协作共同完成开发工作。 3种典型的组织方式:
13.4.1 民主制程序员组 (Democratization Programmers Group) 民主制程序员组的一个重要特点是,小组成员完全平等,享有充分民主,通过协商做出技术决策。 程序设计小组的人数不能太多,否则组员间彼此通信的时间将多于程序设计时间。
民主制程序员组的主要优点是,组员们对发现程序错误持积极的态度,这种态度有助于更快速地发现错误,从而导致高质量的代码。 民主制程序员组的另一个优点是,组员们享有充分民主,小组有高度凝聚力,组内学术空气浓厚,有利于攻克技术难关。因此,当有难题需要解决时,也就是说,当所要开发的软件的技术难度较高时,采用民主制程序员组是适宜的。
13.4.2 主程序员组(Main Programmers Group) 美国IBM公司在20世纪70年代初期开始采用主程序员组的组织方式。采用这种组织方式主要出于下述几点考虑: (1) 软件开发人员多数比较缺乏经验; (2) 程序设计过程中有许多事务性的工作,例如,大量信息的存储和更新; (3) 多渠道通信很费时间,将降低程序员的生产率。 主程序员组用经验多、技术好、能力强的程序员作为主程序员。
图13.5 主程序员组的结构
13.4.3 现代程序员组 (Modernistic Programmer s Group) 主程序员组的组织方式时,主程序员对每行代码的质量负责,因此,他必须参与所有代码审查工作。由于主程序员同时又是负责对小组成员进行评价的管理员,他参与代码审查工作就会把所发现的程序错误与小组成员的工作业绩联系起来,从而造成小组成员出现不愿意发现错误的心理。
图13.6 现代程序员组的结构
当软件项目规模较大时,应该把程序员分成若干个小组,采用图13 当软件项目规模较大时,应该把程序员分成若干个小组,采用图13.7所示的组织结构。该图描绘的是技术管理组织结构,非技术管理组织结构与此类似。由图可以看出,产品开发作为一个整体是在项目经理的指导下进行的,程序员向他们的组长汇报工作,而组长则向项目经理汇报工作。当产品规模更大时,可以适当增加中间管理层次。
图13.7 大型项目的技术管理组织结构
图13.8 包含分散决策的组织方式 把民主制程序员组和主程序员组的优点结合起来的另一种方法,是在合适的地方采用分散做决定的方法。 把民主制程序员组和主程序员组的优点结合起来的另一种方法,是在合适的地方采用分散做决定的方法。