第1章
软件项目管理概述

1.1 项目与软件项目

“软件”“项目”“软件项目”等概念已经越来越被大家所熟悉,并且普遍存在于生活和社会的各个方面。软件行业是一个极具挑战性和创造性的行业,而软件项目管理也是一项具有挑战性的工作,同时,也是保证项目成功的必要手段。

1.1.1 项目及其特征

人类社会和日常生活中有很多的活动,有的活动称为项目,有的活动则不能称为项目。项目(project)是为了创造唯一的产品或提供唯一的服务而进行的临时性的努力;是以一套独特而相互联系的任务为前提,有效地利用资源,在一定时间内满足一系列特定目标的多项相关工作的总称。一般来说,日常运作和项目是两种主要的活动。它们虽然有共同点—例如,都需要由人来完成,均受到有限资源的限制,均需要计划、执行、控制—但项目是组织层次上进行的具有时限性和唯一性的工作,也许只需要一个人,也许涉及成千上万个人,也许需要100小时完成,也许要10年才能完成,等等。“上班”“批量生产”“每天的卫生保洁”等属于日常运作,不是项目。项目与日常运作的不同是:项目是一次性的,日常运作是重复进行的;项目是以目标为导向的,日常运作是通过效率和有效性体现的;项目是通过项目经理及其团队工作完成的,日常运作是职能式的线性管理;项目存在大量的变更管理,日常运作基本保持持续的连贯性。下面介绍项目具有的特征。

• 目标性。项目的目的在于得到特定的结果,即项目是面向目标的。其结果可能是一种产品,也可能是一种服务。目标贯穿于项目始终,一系列的项目计划和实施活动都是围绕这些目标进行的。例如,一个软件项目的最终目标可以是开发一个学生成绩管理系统。

• 相关性。项目的复杂性是固有的,一个项目有很多彼此相关的活动,例如,某些活动在其他活动完成之前不能启动,而另一些活动必须并行实施,如果不能协调地开展这些活动,就不能实现整个项目的目标。

• 临时性。项目的临时性是指项目有明确的起点和终点。临时性并不一定意味着项目的持续时间短。项目要在一个限定的期间内完成,是一种临时性的任务。当项目的目标达到时,意味着项目任务完成。项目管理主要用来保证在预定时间内完成项目任务,为此而制订项目计划进度表,标识任务何时开始、何时结束。项目任务不同于批量生产,批量生产是指相同的产品连续生产,取决于要求的生产量,当生产任务完成时,生产线停止运行,这种连续生产不是项目。

• 独特性。在一定程度上,项目与项目之间没有重复性,每个项目都有其独自的特点。每一个项目都是唯一的。如果一位建筑工程师要按照规范建造第五十栋住宅,该住宅的独特性一定很低,它的基本部分与已经建好的第四十九栋住宅是相同的,如果说它有特殊性,也只是在于其地基不同、使用了一个新的热水器、请了几位新木工等。然而,如果要为新一代计算机设计操作系统,则该工作必然会有很强的独特性,因为没有人做过这个项目,可供参考的经验并不多。

• 资源约束性。每一个项目都需要运用各种资源作为实施的保证,而资源是有限的,所以资源是项目成功实施的一个约束条件。

• 不确定性。项目开始前,应当在一定预算的基础上制订一份计划,但是,在项目的具体实施过程中,外部因素和内部因素总是会发生一些变化,存在一定的风险和很多不确定性因素,因此项目具有不确定性。

1.1.2 项目、项目群、项目组合的关系

图1-1展示了项目、项目群和项目组合之间的关系。

(1)项目与子项目

项目(project)是“为创造唯一的产品、服务或结果而开展的一种暂时性活动”。在软件工程中,有各种类型的项目,如产品开发、外包服务、软件维护服务、服务创建等。在产品生命周期中,可能需要多个项目。例如,在产品概念阶段,可启动一个决定产品目标客户和市场需求的项目,而在产品维护阶段,可设立一个生产该产品下一版本的项目。

图1-1 项目、项目群和项目组合之间的关系

子项目(subproject)是指将项目分解为更小的单位,以便更好地控制项目。项目中的某一阶段可以是一个单独的项目,也可以是一个子项目,子项目可以转包给外部机构的一个单元。在实际工作中,子项目的划分是很灵活的,可以视项目的需要而定。可以按照阶段划分子项目(如一期项目、二期项目……),也可以按照项目的组成部分划分子项目。

(2)项目群

项目群(program)是一组相互联系的项目、子项目以及受控过程的活动。通常使用程序来定义和管控在有限时间内面向单一客户或者市场的不同提交物。项目群也称为大型项目,是通过协调来进行统一管理的一组相互联系的项目,它本身可能不是项目。许多大型项目通常包括持续运作的活动。可以将大型项目理解为比项目高一级别的大项目,如“863计划”“星火计划”“阿波罗计划”等。以“863计划”为例,它的目标是瞄准世界先进水平,集中资源重点投入,争取在我国部分有优势的高科技领域有所突破,为我国在21世纪的经济发展和国防安全创造条件。这样的目标是战略性的,很难具体化,但可以通过一系列的具体项目去实现。

(3)项目组合

项目组合(portfolio)是指把项目、项目群、子组合及操作作为一个整体进行管理。通过组合可对一条产品线或者一个组织内部并存的所有资产进行分组与管理。如果考察一个完整的项目组合,会发现它受到决策的影响。

1.1.3 软件项目

软件一词于1956年在美国被正式提出,是指计算机程序及说明程序的各种文档。软件是计算机系统中与硬件相互依存的部分,是包括程序、数据及其相关文档的完整集合。其中,程序是按事先设计的功能和性能要求执行的指令序列,数据是使程序能正常操纵信息的数据结构,文档是与程序开发、维护和使用有关的图文材料。软件项目除了具备项目的基本特征之外,还有如下特点。

• 软件是一种逻辑实体,不是具体的物理实体,具有抽象性,这使得软件与硬件或者工程类项目有很多的不同之处。

• 软件的生产与硬件不同,开发过程中没有明显的制造过程,也不存在重复生产过程。

• 软件没有硬件的机械磨损和老化问题,然而,软件存在退化问题。在软件的生存期中,软件环境的变化会导致软件的失效率提高。

• 软件的开发受到计算机系统的限制,对计算机系统有不同程度的依赖。

• 软件开发至今没有摆脱手工的开发模式,软件产品基本上是“定制的”,无法利用现有的软件组件组装成所需要的软件。

• 软件本身是复杂的,其复杂性来自应用领域实际问题的复杂性和应用软件技术的复杂性。

• 软件的成本相当高昂。软件开发需要投入大量资金和高强度的脑力劳动,因此成本比较高。

• 很多软件工作涉及社会的因素,例如,许多软件开发受到机构、体系和管理方式等问题的限制。

软件项目是一种特殊的项目,它创造的唯一产品或者服务是逻辑载体,没有具体的形状和尺寸,只有逻辑的规模和运行的效果。软件项目不同于其他项目,软件是一个新领域而且涉及的因素比较多,管理起来比较复杂。目前,软件项目的开发远远不如其他领域的项目规范,很多理论还不适用于所有软件项目,经验在软件项目中仍起很大的作用。软件项目由相互作用的各个系统组成,“系统”包括彼此相互作用的部分。软件项目中涉及的因素越多,彼此之间的相互作用就越大。另外,变更也是软件项目中常见的现象,如需求的变更、设计的变更、技术的变更、社会环境的变更等,这些均说明了软件项目管理的复杂性。项目的独特性和临时性决定了项目是渐进明细的,软件项目更是如此,因为软件项目比其他项目有更大的独特性。“渐进明细”表明项目的定义会随着项目团队成员对项目、产品等的理解和认识的逐步加深而得到逐渐清晰的描述。软件行业是一个极具挑战性和创造性的行业,软件开发是一项复杂的系统工程,牵涉各方面的因素。软件项目的特征包括需求的不确定性和开发过程中存在技术风险。在实际的软件项目开发工作中,经常会出现各种各样的问题,甚至软件项目会失败。如何总结、分析项目失败的原因并得出有益的教训,是今后项目取得成功的关键。

现阶段,软件的发展存在以下五大趋势。

• 计算技术重心转向网络,互联网成为软件开发、部署和运行的平台。

• 软件服务化趋势逐步从以应用和软件产品为中心转移到以客户服务为中心。

• 智能化趋势逐步由物理传感器状态感知分析向人类意识思维方向转变。

• 操作系统、数据库、中间件和应用软件等相互融合,向一体化平台发展。

• 大量创新技术、业态模式推动人类社会、国民经济各行业、数字经济市场快速发展。

1.1.4 软件项目组成要素

简单地说,项目就是在既定的资源和要求的约束下,为实现某种目的而相互联系的一次性工作任务。软件项目的要素包括软件开发的过程、软件开发的结果、软件开发赖以生存的资源及软件项目的特定委托人(或者说是客户,既是项目结果的需求者,也是项目实施的资金提供者)。

软件项目的目标就是在一定时间、预算内完成项目范围内的事项,以使客户满意。一个成功的软件项目应该在项目允许的范围内满足成本、进度要求,并得到客户满意的产品质量。所以,软件项目目标的实现受4个因素的制约:项目范围、成本、进度计划和客户满意度,见图1-2。项目范围是为使客户满意必须做的所有工作。成本是完成项目所需要的费用。进度计划安排每项任务的起止时间及所需的资源等,为项目描绘一个过程蓝图。客户是否满意要看项目交付的成果质量,只有客户满意才能更快地结束项目,否则会导致项目的拖延,从而增加额外的费用。

图1-2 软件项目目标实现的制约因素

1.1.5 软件工程发展阶段

按照某些专家的说法,可以将软件工程划分为三个时代。1968年“软件工程”学科诞生为第一代软件工程,即软件工程1.0;2001年敏捷宣言发布意味着进入第二代软件工程,即软件工程2.0;2023年以ChatGPT为代表的大模型爆发表明进入第三代软件工程,即软件工程3.0,如图1-3所示。

1.第一代软件工程

第一代软件工程是指受建筑工程、水利工程等影响的传统软件工程,它的诞生可以追溯到1968年。20世纪五六十年代出现了软件危机,布鲁克斯(Frederick P.Brooks)在《人月神话》一书中写道:软件开发被喻为让众多史前巨兽痛苦挣扎,却无力摆脱的焦油坑。软件危机迫使人们去寻找产生危机的内在原因,进而找出消除危机的解决方案。面对软件危机,人们调查研究了软件开发的实际情况,逐步认识到采用工程化的方法从事软件系统的研发和维护的必要性。为了克服这一危机,大家走到一起,共同探讨以获得问题的解决途径。1968年北大西洋公约组织(NATO)的计算机科学家在德国召开国际会议,讨论软件危机问题,正式提出了“软件工程”(software engineering)的概念,从此一门新的工程学科诞生了。软件工程自此得以不断发展并逐渐成熟起来。传统软件工程主要向土木工程、工业工程学习,吸收其实践方法和经验。软件工程1.0体现了以下特征。

• 产品化:交付符合质量标准的组件、构件和系统。

• 过程决定结果:流程质量决定产品质量,一环扣一环,相信良好的过程产生良好的产品,关注过程胜过关注人,也非常关注过程评估和过程改进,如CMM(能力成熟度模型)是其典型代表。

• 阶段性明确:需求评审通过了,才能开始设计;设计评审通过了,才能开始实施(编程);编程结束了再进行测试等。瀑布模型是其典型代表。

• 责任明确:角色定义清楚,分工细致。

• 文档化:强调规范的文档,存在大量的文档模板。

• 计划性强:具有完整的计划,严格控制变更。

• 建筑工程的框架结构设计,在软件工程上表现为以架构设计为中心。

• 现代制造业流水线的启发—软件工厂思想。

• 注重项目管理:围绕项目开展管理工作,包括风险预防、里程碑控制和关键路径法等。

• 以顾客为中心的全面质量管理。

• 预防为主,检验为辅,即缺陷预防思想。

图1-3 软件工程的三个时代

2.第二代软件工程

受互联网、开源软件运动、敏捷/DevOps开发模式所影响并最终形成的建立在SaaS(软件即服务)、云计算基础之上的软件工程被定义为“软件工程2.0”。软件工程2.0的特征可以简单概括为下列几点。

• SaaS:软件更多是以服务的形式存在。

• 以人为本:个体与协作胜于流程和工具,充分发挥个人和团队的创造性和潜力。

• 拥抱变化:敏捷开发或轻量级过程,加速迭代,以不变应万变。

• 持续性:阶段性不明确,持续构建、持续集成、持续测试、持续交付,以时间换空间,消除市场风险。

• 融合:强调测试与开发融合、开发与运维融合、推崇全栈工程师等。

• 真正把用户放在第一位:用户、产品经理尽可能参与团队研发过程,注重用户体验。

• 强调价值交付:只做对用户有价值的事情,加速价值流的流动。

• 知识管理,将软件工程纳入知识管理的范畴。

• 史诗般故事、用户故事、站立会议,让软件开发工作更有趣、更健康。

3.第三代软件工程

在技术突破和创新方法的推动下,软件工程的发展越来越快,而GPT-4等人工智能(AI)语言大模型的出现也改变了很多行业,对软件研发的影响更为显著。考虑到它的发展速度,在不久的将来,AI将开始逐渐承担一些软件研发的工作,通过将GPT-4+(指GPT-4及其未来升级的版本)融入软件研发生命周期中,研发人员的使命将发生变化。GPT-4+将重新定义开发人员构建、维护和改进软件应用程序的方式,之后的软件开发会依赖这种全新的语言交流方式(类似ChatGPT),让这类工具理解研发人员交代的任务并自主完成软件开发,如理解需求、自动生成UI、自动生成产品代码、自动生成测试脚本等。此后,研发团队的主要任务不是写代码、执行测试,而是训练模型、进行参数调优、围绕业务主题提问或给提示。因此,我们说GPT-4将开启“软件工程3.0”新时代。软件工程3.0具有以下特征。

• 数字化:软件研发平台开始能够理解需求、设计、代码等,软件研发从过去的信息化进入数字化时代。

• AIGC:生成软件的各种ware:验收标准、测试用例、UI、代码、测试脚本等。

• 极致的持续交付:虽然软件工程2.0开始面向CI/CD,但还存在许多障碍,而软件工程3.0,得益于设计、代码、测试脚本等的自动生成,可以真正实现持续交付,即及时响应客户需求,交付客户所需的功能。

• 人机交互智能:软件研发过程就是人与计算机的交互过程。

• 以模型和数据为本:研发人员服务于大模型和大数据平台,包括模型的创建、训练、调优、使用等。

不同时代的软件工程,对于软件项目管理体现为不同的管理方法和模式。软件工程1.0体现为传统软件项目管理模式,软件工程2.0更多是敏捷化项目管理,同时与传统软件项目管理并存。对于软件工程3.0,智能化时代改变了软件开发方式,软件项目管理的方式也应该随之有所改变。