UML软件工程组织

通过类比介绍 IBM Rational Unified Process 的要点
作者:Mats Wessberg

为了向初学者介绍 RUP 框架,软件开发的过程经常和建筑过程相比较。但是和建造房屋比起来,使用 RUP 进行软件开发更像是在制作电影,这正如文章题目所说的那样。

每个 IBM Rational Unified Process 框架的新用户都容易因为它的大小,因为它包含的上百个工件和活动而感觉到沮丧。但事实上理解 RUP® 框架的要点是相对容易的,特别是在介绍时把它们同一些熟悉的过程相类比。一个常用的类比是将使用 RUP 进行软件开发的过程和建造房屋的过程相比较。我感觉这种类比有一些缺乏考虑,而我在本文中打算使用另一个不同的类比。我认为使用 RUP 框架创建软件系统的过程在很多方面同构思并制作一部长的电影很类似。

用建造房屋类比的问题
我经常会奇怪为什么 RUP 经常被比作建造房屋的过程。我理解这样类比的动机,是为了向 RUP 的新用户提供一种他们熟悉的类比。毕竟这是关于使用类似的角色和词汇的关于构建有形实体的过程。作为软件系统,必须在建造墙和屋顶之前完成地基(软件方面的架构)。但是在其他方面,这两个过程并不很相似。例如,软件架构设计师处理诸如软件系统内部工作之类的问题。而另一方面,建筑师更关心外观上和功能上的设计,这和软件领域的系统分析师更类似。深入的钻研这两个过程就很容易发现他们之间其他的分歧。对于将这二者进行类比,我主要的异议在于,建造房屋的过程可以是完全可预知的瀑布式的过程(参见图1),而软件开发的过程不能!

图1.传统的瀑布式建筑过程
图1.传统的瀑布式建筑过程

土木工程师可能会不同意,并且认为建筑项目中和软件项目中的问题是共同的。然而事实是土木工程依靠的是一些众所周知的物理定律,而软件工程不是!

考虑到这些问题,促使我们怀疑是否能够找到除了建筑过程以外更好的一个类比来向人们介绍 RUP 框架。我似乎觉得尽管RUP和工程过程一样有着基本的目标和策略,但事实上实现这些目标的过程和艺术领域内使用创造性方法的过程更有共同点,如拍电影,写书,甚至写一篇类似本文的文章。因此当我介绍了RUP的基本原理后,我将会阐述这些要点是怎样和电影制作相对应的。

RUP的基本原理
和大多数人的看法相反,RUP框架并不是治疗不良软件开发实施的良药。RUP以常识为基础,由许多成功的软件项目而产生。有趣的是这样类似的实践也存在于其他领域内。

在任何类别的开发中使用任何工序的唯一目的就是为了减小风险。更具体的说,使用RUP是为了减小软件开发相关的风险。通过遵从精心设计并已被证明了的规则,我们的目的是增加成功的可能性。毕竟,如果软件设计是可以预测的事情,我们为什么要费如此的力气呢?

一部分软件开发相关的风险和其他类型开发的风险一样,包括以下几点:

  • 实现项目的资源不足
  • 资金不足
  • 任务太多,时间不足
  • 不成熟,响应速度慢,或不灵活的组织

这些是管理风险的例子,可以由经济手段,结构改革,或教育方面的努力来解决。

但仍然有一些风险和软件开发不可预测的特点相关,如下所示:

  • 未知的技术
  • 未发现的需求
  • 复杂的结构

后者是更加技术化的风险,必须用其他方法解决。为了处理这样的风险,RUP给出了以下这些主要的策略:

  • 开发迭代
  • 管理项目需求
  • 使用基于组件的体系架构
  • 可视化建模
  • 持续的质量验证
  • 管理变更

这些策略作为最佳实践在 Rational Unified Process 中经常提到。普遍的讲,这些规则并不局限于软件开发领域,而是更加通用和可以用来在不同的情况下处理问题。在下一节我们将深入的分析每一个最佳实践,讨论它们如何同电影制作相对应。在本文的最后我将提到一些其他的可能从RUP最佳实践中受益的项目类型。

开发迭代
创新性的创造工作,无论是制作电影画面还是软件,在完成最终产品的过程中都需要在同一工件上反复的尝试。

使用瀑布式开发策略时(如图1所示),项目周期是顺序的,它将项目中潜在问题的发现时间推迟到项目完成和测试之时。所有隐藏在需求、设计和编写代码过程中的问题在项目结束时突然的显现出来,的确是很棘手的。而开发迭代允许项目小步进行或增长,逐渐完成整个系统。

如图2所示,RUP中的每一次迭代都要经过这些规程。(RUP中的规程可以被描述为相关的活动、工件或生成的可交付工件。)每一次的迭代都像是一个小的“瀑布”,发现需求中新的部分,提供改正错误的机会并且再次处理上一次迭代的结果。随着不断的迭代,越来越接近最终的产品。

图2.RUP的迭代开发流程
图2.RUP的迭代开发流程

你可能会认为电影制作是一个直进的过程,首先写剧本,然后解决如何将文字表现为动作,拍摄电影并剪辑,最后观看效果。这可能是一个传统的瀑布式方法。但正如这种瀑布式方法在编写软件时是失败的一样,在电影制作时这种方法也会失败。幸运的是(对于常看电影的人来说),电影不是这样拍成的。

电影拍摄的过程是更加迭代性的。演员的工作从剧本开始,由这种交互开始修改。例如,轰动一时的 指环王,它的剧本基于J.R.R. Tolkien的名著,几乎每天都在和演员的交互后进行修改。导演Peter Jackson把这一创新性的过程描述为控制下的混沌。在电影结束之前,剧本被修改了很多次。每一次修改(或迭代)都产生了一个更多的(也是更好的)版本,更加接近最终的版本。

管理项目需求
当进行任何种类的产品开发时另一项基本的任务是保证它符合用户的需要。最终的目标是减小建构系统的不必要风险——也就是说,不符合用户需求的。这可能是一个棘手的任务,由于有时候用户对开发中的产品仅仅有一个模糊的想法,而需求并不是同等重要或简单的,而且,所有这些参数(和其他的)必然会随时间而变化。这样,一个初始设定好的需求集似乎并不是很好,但一种主动的需求管理策略可以迭代的改进当前的需求,满足用户需要。

RUP在软件的开发周期内进行需求管理。这意味着项目需求会被反复和逐渐的确定,证明,评估和改进。功能性的需求用使用用例的术语来描述。软件系统中非常重要的非功能性的需求,也应该被确定和管理。这些需求是不是通过用例来描述的,但他们通常是对系统有很大影响的系统特性,包括系统可用性,可靠性,系统性能和可支持性。

当电影制作人工作时,他们必须考虑迎合观众的需要。他们需要电影激发起什么样的感情?何种体验是观众想要的?他们希望这个故事在哪里上映?电影剧本经过多次迭代,逐渐调整直到导演看来符合这些功能性的需求。

如果软件的功能需求已经在电影上有了对应部分,那么电影有非功能需求吗?答案(并不令人惊讶的)是有的。也许(出于商业上的原因)电影必须能被18岁以下的儿童观看并且不长于120分钟。尽管这些需求并不直接与故事情节相关,它们还是对最终的结果有着潜在的影响——正如计算机系统上必须有非功能性软件需求一样。同样的,这些需求必须在电影制作的过程中确定和提出。

使用基于组件的体系架构
组件是一个具有清晰功能的可替换的软件模块。RUP鼓励使用组件来组合成一个系统。基于组件的开发有以下的优点:它使软件在本系统和其他系统中的重新使用上更加方便,它在系统设计中提供了方便的抽象概念,并且它允许高效的并行开发。此外,精心设计的基于组件的架构使得系统更加容易升级和维护。

在电影中最显而易见的是场景。一部电影一般由具有连贯情节的许多场景组成,这些场景实现导演的想法。每一个场景都是可替换的,意味着可以替换、修改,甚至删除这个场景而不影响到整个电影(如果导演需要的话)。

不使用基于组件的架构的原则来开发一个很大的计算机应用程序,像现在仍然有的作法那样,就如同仅仅拍摄一次就完成整个电影一样。这就是2002年Aleksandr Sokurov 的电影《俄罗斯方舟》的拍摄手法——整个电影(2小时16分)是一个连续的拍摄过程。由于即便是拍摄一段十分钟的连续场景都是非常困难的,Sokurov的成就的确是很了不起的。回到软件领域内,RUP基于组件的架构使软件开发者不再像英雄一样要完成不可能的需求。

电影和软件组件中另一个并不明显的对应例子来源于 Pixar 近期的成功之作。在制作电脑动画冒险片 Finding Nemo过程中,制作者面临的一个挑战是创造逼真的海浪和潮水。(Finding Nemo 这个故事或多或少的发生在海底世界中。)问题不仅在于准确的模拟海水的运动,更在于捕捉光线的反射,水珠的飞舞,不同类型海水的颜色,等等。在电脑动画中,从来没有人能够做到这种程度。

在项目开始时,设计部门开始对海水的模型作实验。他们进行了广泛的研究,咨询了海洋学专家,勾画了草图和画面,最重要的是,基于他们在这个问题上不断增长的知识创建了原始模型。原始模型经过导演挑剔的目光,这些繁重工作的最后结果是一个设计模板,它涵盖了对电影中各种可能的海水的模拟。这个模板是这部电影架构中的基本组件,其他的组件(模板)解决了不同的问题,比如鱼和植物的运动模式。

在软件开发领域,设计模板告诉设计者怎样处理最重要的问题。没有一个坚实的架构,或设计模板,就不会有项目大幅度的前进。设计者没法满足需求,直到解决了这些问题。

可视化建模
模型是现实世界实体或过程的简化表达,它帮助我们想象和勾画出现实世界的形象。在软件开发早期的一些时候,需要理解系统和用户之间的关系。开发者有两个选择:他们可以按照他们猜想的软件工作方式去实施软件,或者创建一个模型,这个模型会提供给潜在的用户,设计者和测试人员,由他们的反馈再对模型进行变更。

模型的类别描述了用户怎样和系统交互,它经常被作为用例被提及。创建用例模型的要点是减小错误构建系统的风险。在RUP中还有其他类别的模型,每一种用来减小特定的风险。潜在的假设是在系统模型中比在实物中更有利于发现错误和缺点。处理这些模型是犯错的最廉价方式。

通常来说,建模是有些理论性的实践,它有助于我们用简化的方法去理解复杂的系统。原型是一种非常有帮助的建模类型,它可以用于模拟,原理测试,或者设计的特定方面的实际工作。原型用于生成能够说明系统某方面或某种特性的信息。RUP鼓励架构设计组通过创建原型来证明他们的架构概念。

在拍摄电影的前期,只有剧本。但就和软件项目一样,导演需要在完成之前看到电影的样子。如同使用RUP一样,解决方法是建立一个故事的模型。在电影工业中这称为可视化,它可以用不同的技术来实现:传统的方式有演员扮演,木偶扮演,情节串连图板,甚至3D电脑图像。如果使用情节串连图板(顺便说一下,它同样是存在于RUP中的一个概念)的话,这个模型由一系列反映舞台或场景的草图组成。为了进一步增强这一模型的用途,情节串连图板可以被拍成电影并进行修改,可以加上临时的音效和配乐。

在软件开发和电影制作中,建模都是一个动态的,无序的,创性的过程。许多时候需要一次次的迭代进行,直到完成一个令人满意的结果。

持续的质量验证
日常生活中和软件项目开发中,每一件事都要占用时间和空间。RUP分为四个阶段,每一个阶段的重点放在开发周期内一个特定的方面:起始,精化,构建和产品化。在每一个阶段中RUP的最佳实践给我们机会验证开发中项目的进度和质量,从而尽可能早的找到错误和潜在的改进。

在起始阶段,重点是理解项目的目的。通过探索需求来实现,确定可能会发生的主要风险以及之后可能会出现问题的地方。在这个阶段结束前需要回答的问题是,这个项目是不是值得去做。进行一个没有价值的项目只能浪费时间,浪费可以投到有价值项目上的金钱。这一类的问题必须尽早的得到处理。

当一个项目需要继续时,就进入了精化阶段。这里的重点是建立一个坚实的设计基础(架构)以及减小项目主要的风险。分析完需求之后,根据对架构影响最大的需求定制架构是很必要的。当架构已经确定并且被证明符合重要需求之后,填充系统功能就很安全了。因此,你必须停留在精化阶段直到你证明了你的架构是有效的。

概括地说,在RUP中,每一次迭代都要检验上一次增加的质量。我们首先检验我们是否已经理解了问题,并且存在一个可靠的业务场景。如果不是,我们或者继续直到达到了这一点,或者停止这个项目,节省时间和金钱。在我们填充系统功能之前,我们同时也检验是否已经建立了一个十分牢固的架构。持续的质量验证最佳实践可以使这样做变得容易。

在电影项目中,导演首先使用模型工具发现分期的故事情节,不吻合的场景,或不适当的节奏等问题。问题较早的发现之后,处理它们就比较简单了。电影制作和软件开发一样,普遍的规则是问题发现越早,修改成本越低。

管理变更
我想我们都同意变更是必然的,但又是不容易处理的。需求总是随着时间不可避免的变化,由于许多不同的原因——项目的投资者改变了主意,开发者对需求有了更深的认识,设计决定产生的效果变得明显,等等。确定变更的必要性是一件事,但是做出变更是另一件事。瀑布式开发经常失败的一个原因是,他不能够处理变更。与此相对比,迭代和增量式方法使得连续的变更更加容易,迭代会得出更好的解决方案。

拍一部长片是一项浩大的任务,它包括管理一个巨大的团队和充足的预算。对于这样一个项目来说,和必须要做的变更保持良好的沟通是成功的关键。可以想象,导演希望改进最后一个场景。尽管它在电影的末尾,但改进的需要可以很早就确定下来,因为在每一个级别上都连续的检验质量。编剧必须修改剧本吗?谁去审查和改进影片?这个场景需要重新建模吗?如果是的话,要使用情节串连图板、3D图像、还是塑料模型?布景需要修改,还是重新建一个布景?我们需要寻找新的位置吗?我们需要请特技演员吗?这些变更对我们的预算影响如何?我们需要请求更多的时间和经费吗?这些就是在变更计划时遇到的种种问题,它们必须被处理,处理他们更适合使用迭代的方式。

一个电影项目计划
RUP框架中一个关键组件就是项目计划。项目计划详细描述了任务、时序、成本、资源、里程碑,和完成项目所需的可交付工件。进度按照计划来执行,并且根据已完成的工作来度量——根据达到的里程碑和交付的结果。在项目开始就构思了这个计划,并且在项目的生命周期内这个计划经常变更。

项目计划像RUP框架一样,很容易适用于软件开发之外的项目。作为一个例子,让我们看一看一个很粗略的电影项目计划。

在这个例子中,RUP规程被电影制作相关活动所取代。开发电影剧本和撰写需求类似,拍摄电影和实施类似,制作电影或多或少和项目管理类似。把时间表分为四个部分,这样在不同的时间将重点放在电影制作不同的方面。我们也能发现这些活动是并行的,通常高效的,跨功能的交换信息和工作成果——就像RUP中那样。

将RUP应用于其它类型的项目
RUP的原理并不仅仅针对软件开发或电影制作。在不可靠性是首要问题的情况下,这些原理都是可用的。在这种情况下,无论你花多少时间多少精力,预先计算出结果是不可能的。更普遍的讲,RUP的原理可以应用于具有以下特性的项目中:

  • 产生可交付工件的项目
  • 解决方法一定程度上未知的项目
  • 不可预期性是关键因素的项目

以下是RUP原理可能有帮助的一些项目例子:

  • 如果你要写一本有关C++编程的书,你首先的目标是可交付工件(这本书本身)。这本书的内容和结构,它的关键章节,教学方法都是这本书中未知或不可预期的例子。首先你要确定目标读者,并且为每一章写一个简短的描述。之后,你可能会细化关键章节,在进行其他部分之前检查这些章节。最后一步是完成全书,交送给出版商。
  • 如果你要进行如何在软件组织中增强测试能力的研究,可能会期望你完成一些报告。首先你需要理解这些问题,制定一个粗略的时间安排和调查期间的资源保护。之后,在你能够更新并且随着对问题的深化交流计划之前,你会尝试用不同的方法来减小主要的不确定性。消除了高的风险后,你可以继续进行研究。最后,你撰写报告,获得客户的同意。并不是巧合,许多研究方法都基于同RUP类似的原理。
  • 如果你要在一个组织中实施RUP,你通常应从确定风险、机会,和创建高级使用方案开始。你可能会在第一个项目中从实施最关键部分(依目标机构的情况而定)开始,而将并不重要的部分留到以后的项目中完成。对于一个更加有能力的开发组织,可交付工件将是一个文档化的RUP过程配置。

小结
RUP提供了带有规程和实践的框架,它可以减小软件开发的不可预知性。此外,RUP 的基本原理可以用来解决其它类型的不可预知问题,如电影制作或撰写书籍。遵从RUP 并不能使得软件开发——或电影制作——更加简单。总的来说,和传统的开发相比,这是一条艰苦的路。然而在这条路上的努力被证明是有价值的,因为我们可以得到回报:改善的产品质量和更加可预测的开发成果。

 

版权所有:UML软件工程组织