UML软件建模技术
上QQ阅读APP看书,第一时间看更新

1.2 软件工程与Rational统一过程

内容提要

软件是包括程序、数据及其相关文档的完整集合,其开发过程至今尚未摆脱手工艺的开发方式,随着软件复杂度和开发难度的日益增加,逐渐形成了所谓的软件危机。为了解决软件危机,计算机科学家提出了软件工程的概念——使用工程化的原则和方法组织软件开发工作。本节重点介绍了软件的生存期和几种典型的软件生存期模型,最后介绍了Rational统一过程(Rational Unified Process,RUP)。本节主要内容如下:

• 软件

• 软件生命周期

• 软件生存期模型

• RUP

1.2.1 软件

在了解软件工程之前,我们首先需要知道什么是软件。一些人认为,软件就是程序,就是代码,这是一种片面的理解。软件一词最早是20世纪60年代初从海外传来的,当时很多人都无法给出确切的含义。现在普遍认可的定义是:软件是计算机系统中与硬件相互依存的另一部分,它是包括程序、数据及其相关文档的完整集合。其中,程序是按照事先设计的功能和性能要求执行的指令序列,数据是使得程序能够适当地操作信息的数据结构,文档是描述程序的开发、操作和维护的文字或图形资料。

要理解软件的概念,需要先了解软件的特征,这样就能够理解软件与其他事物之间的区别了。软件是一种逻辑实体,而不是具体的物理实体,因此,它具有与硬件完全不同的特征。

1. 软件是被设计开发的,而不是被制造的

虽然软件开发和硬件制造之间有一些相似之处,例如都可以通过良好的设计得到高质量的产品,但两类活动存在本质上的不同。软件的开发过程中没有明显的制造过程,因此,硬件在制造过程中可以进行质量控制,而这种情况对软件而言几乎是不存在的。如果要对软件进行质量控制,就必须在软件开发和测试方面下工夫。另外,就软件集中开发的特点而言,软件项目也不能像制造类项目那样管理。

2. 软件不会“磨损”,但会“退化”

硬件在运行和使用期间,会有机器磨损、老化等问题。如:硬件在其生命初期有较高的故障率,这些故障主要是设计或制造的缺陷;在中期,随着缺陷的修正,故障率会维持在一个较低的水平上;到了后期,故障率又提升了,这是因为硬件已经进入了“磨损期”。而软件的情况不同,它不存在磨损和老化问题,但存在着退化问题。在软件的生存期中,会经历多次修改或维护,使它能够适应软硬环境的变化以及用户的新要求,但每次修改都可能会引入新的错误,这样一次次修改,导致软件故障率提高,从而使软件退化。

另外,当一个硬件零件磨损的时候,可以用另外一个来替换,但软件就没有备用零件可换。每一个软件故障都表明了设计或者是编码中存在着错误。因此,软件维护比硬件维护复杂得多。

3. 软件的开发至今尚未摆脱手工艺的开发方式

考虑这样一个案例:硬件设计工程师设计一个简单的数字电路图,其中的每一个集成电路都有一个零件编号,都有统一的制造工艺标准。每选定一个零件,我们都可以在货架上很方便地买到。硬件设计工程师可以专注于设计中的创新部分,而集成电路等零件是已经标准化的部件,可以不断复用,不需要硬件设计工程师再重新设计。类似的,一个软件设计师设计一个简单的应用系统,它包含多个子系统,我们可以把子系统想象成硬件世界中的“零件”,但这些“零件”不是标准化的工业产品,也不能在任何的货架上买到。因此,软件设计师完成了这个简单的应用系统的设计工作之后,还必须花额外的工夫去一一实现每个子系统。

在硬件世界,部件复用是工程过程的自然的一部分,但在软件世界,一切才刚刚起步。近年来,软件技术虽然提出了许多新的开发方法,例如复用技术、自动生成技术,但在整个软件项目中采用的比例仍然比较低。大多数软件是根据客户需求定做的,而不是利用现成的部件组装成所需要的软件。由于在软件开发过程中,手工艺开发方式占主流,所以开发的效率自然比较低。

4. 软件是复杂的

软件的研制工作必须要投入大量的高强度的脑力劳动,所以有人认为,人类创造的最复杂的产物是计算机软件。软件的复杂性可能来自它所反映的实际问题的复杂性,例如,它所反映的自然规律或是人类社会的各种活动,都具有一定的复杂性;另一方面,软件的复杂性也可能来自程序逻辑结构的复杂性,例如,一个系统软件要能处理各种可能出现的情况。软件开发常常涉及其他领域的专门知识,这对软件人员提出了很高的要求。现阶段,软件技术的发展落后于复杂的软件需求,这确实是个很现实的问题。

以上讨论的是软件的特征。那么软件究竟有哪些类型呢?在某种程度上我们难以给出一个通用的分类,但鉴于不同类型的工程对象,对其进行开发和维护有不同的处理方法,因此对软件的类型仍需进行必要的划分。下面依照软件的不同功能对软件进行了划分,需要注意的是,划分的方式不是唯一的,从不同的角度出发,可以做出不同的软件划分方式。

(1)系统软件。

是指能与计算机硬件紧密结合在一起,使计算机系统各个部件、相关软件和数据协调高效地工作的软件,如操作系统软件、数据库管理软件、通信处理软件等。

(2)支撑软件。

是指协助用户开发软件的工具性软件,包括帮助程序员开发软件产品的工具,也包括帮助管理人员控制开发的进程的工具,如Java开发工具Eclipse等。

(3)应用软件。

是指在特定领域内开发,为特定目的服务的一类软件。应用软件的种类非常繁多,如计算机辅助设计制造软件、系统仿真软件、人工智能软件、办公自动化软件、计算机辅助教学软件等。

1.2.2 软件危机

早期的程序开发者只是为了满足自己的需要,这种自给自足的生产方式是软件开发低阶段的表现。随着计算机硬件技术的进步,生产硬件的成本降低了,这使得对软件有了更高的要求,所以出现了一些复杂的、大型的软件项目。但是,软件技术的发展落后于软件复杂的需求,随着问题的日积月累,在20世纪六七十年代逐渐形成了所谓的软件危机。软件开发中出现的问题归结如下。

(1)软件开发无计划性,进度的执行和实际情况有很大差距。

(2)软件需求分析阶段工作做得不充分,前期问题不及时解决,造成后期矛盾的集中暴露。

(3)软件开发过程中没有统一的规范指导,参与软件开发的人员各行其事。

(4)软件产品无评测手段。

1.2.3 软件工程

从上述体现软件危机的现象中可以看出,摆脱危机不是一件简单的事情。我们如何开发软件,如何维护大量已有的软件,以及开发速度,如何跟上对软件越来越多的需求等,确实是一大堆苦恼的问题。经过许多计算机软件科学家的实践和总结,得出一个结论:使用工程化的理论和方法组织软件开发工作能有效地解决这些问题,也是摆脱软件危机的一个主要出路。这就引出了软件工程的概念。软件工程是指:将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件开发。

如果不考虑应用领域、项目规模和复杂性,与软件工程相关的工作一般可分为3个阶段。

(1)定义阶段。该阶段关注于“做什么”。软件开发人员在该阶段需要弄清楚要处理什么信息,完成什么样的功能,达到什么样的性能,希望出现什么样的系统行为,建立什么样的界面,有什么设计约束,以及实现一个成功系统的验收标准是什么。

(2)开发阶段。该阶段关注于“如何做”。软件开发人员需要进行如下工作:数据如何被结构化,功能如何被实现于软件体系结构中,界面如何表示,设计如何被翻译成程序设计语言,测试如何进行。

(3)支持阶段。该阶段关注于“变化”。在已有软件的基础上,软件开发人员需要纠正软件中可能存在的错误,为适应外部环境的变化而修改软件,为扩展原来的功能需求而增强和升级软件。

如同任何事物一样,软件也有一个孕育、诞生、成长、成熟、衰落、死亡的生存过程,这个过程称为软件生存期。根据这一思想,将上述3个阶段的活动进一步展开,就得到了软件生存期的6个步骤。

(1)计划。确定要开发软件系统的总目标。由系统分析员和客户人员合作,进行该软件项目的可行性研究,探讨解决问题的可能方案,对开发成本、开发收益、开发进度做出估计,最后制订出详细的软件开发实施计划。

(2)需求分析和定义。对客户提出的需求进行详细的分析。系统分析员和客户人员共同商讨哪些需求是可以满足的,并对其进行准确的描述,最后编写出项目需求说明书。

(3)软件设计(详细设计)。在设计阶段,系统分析员和软件设计人员一起把已经确定了的各个需求转换成相应的体系结构。结构中的每一组成部分都是意义明确的模块,每个模块和某些需求相对应。该阶段的成果物是设计说明书,该说明书对每个模块进行了详细的描述。

(4)编码。软件设计人员和程序员一起将软件设计转换成程序代码。该阶段的成果物是程序清单。

(5)软件测试。软件测试人员设计各种测试用例来检验软件。测试是保证软件质量的重要手段。该阶段的成果物是测试用例书、测试数据和测试结果。

(6)运行和维护。已交付的软件投入正式使用后,就进入维护阶段。软件在运行过程中可能由于多方面的原因,需要对它进行修改。维护的工作可能包括:在软件的运行过程中发现了错误需要修正,给软件做适当变更以适应变化了的软件工作环境。

为了更直观地反映软件生存期内各种活动如何组织、实施,往往需要用软件生存期模型来给出直观的表达。软件生存期模型是从软件项目需求定义直至软件废弃为止,跨越整个生存期的系统开发、运作和维护所实施的全部过程、活动和任务的结构框图。到目前为止,已经提出了多种软件生存期模型,下面只简要地介绍两种。

(1)瀑布模型。该模型规定了计划、需求分析、设计、编码、测试、维护这6个步骤自上而下、相互衔接的固定次序,如同瀑布流水,逐级下落,如图1.2.1所示。

35208-00-020-1.png

图1.2.1

瀑布模型中每一项开发活动有如下的特征:每一项活动的输出(工作成果)都是下一项的输入(除了“运行/维护”活动),在输出的时候要对该项活动实施的工作进行评估,若其工作得到确认则继续进行下一项活动(见图1.2.1中向下指的箭头),若工作不能通过评估,则返回前一项目,甚至更前项的活动进行返工(见图1.2.1中向上指的箭头)。

瀑布模型的缺陷是缺乏灵活性,特别是无法解决软件需求不明确或不准确的问题。

(2)原型实现模型。考虑这样的情况,客户定义了软件的一般性目标,但不能标识出详细的输入/输出及处理要求,或者软件开发人员不能确定算法的有效性或人机交互的形式,但是往往开发人员对软件的认识不够清晰,因此项目无法做到一次开发成功,这使得返工成为必然。在这种情况下,可以考虑用原型实现模型方式来开发软件项目。第一次的开发只是试验开发,其目的在于探索可行性,弄清软件需求。第一次得到的试验性产品称为“原型”。以“原型”为基础,再进行第二次、第三次的开发,逐步调整原型使其满足客户的要求,同时也使得软件开发人员对该软件的实现方法有更深入的理解。这是一个不断完善“原型”,不断迭代的过程,直到最后得到一个客户满意的模型为止,如图1.2.2所示。

35208-00-021-1.png

图1.2.2

1.2.4 面向对象软件工程方法

面向对象技术是一个非常实用而且强有力的软件开发方法,和传统的软件工程方法相比较,它有许多新特色。面向对象技术导致复用,而程序构件的复用导致更快的软件开发和高质量的程序。

为了讨论面向对象软件工程方法,首先必须明确什么是“面向对象”。一个比较统一的认识是:“面向对象=对象+类+继承+通信”。如果一个软件系统是使用这样的概念设计和实现的,就可以认为这个软件系统是面向对象的。

(1)对象。对象是面向对象开发模式的基本组成部分。对象是一种看问题的观点,是对现实世界各种真实事物的一种抽象。一个对象是一组属性和一组操作的集合。属性描述了该对象区别于其他对象的一些重要特征,属性一般只能通过执行对象的操作来改变。操作又称为方法,在C++中称为成员函数,它描述了对象所具有的行为,或者可以执行的功能。对象既含数据又含处理数据的功能,因此,对象被认为是迄今最接近真实事物的数据抽象。

(2)类。类是具有相同属性、相同操作的一组对象的集合的抽象描述。类的定义包括一组数据属性和在数据上的一组合法操作。类定义可以视为一个具有类似特征与共同行为的模板,用来产生对象,因此,每个对象都是类的实例。

(3)继承。继承是使用已存在的定义作为基础建立新定义的技术。一个子类X继承父类Y的所有属性和操作,这意味着,所有原本针对Y设计和实现的数据结构和算法对X是立即可用的,不需要进行进一步的工作。

(4)通信。一个对象和另一个对象之间,通过消息来进行通信。消息是一个对象发出的让另一个对象做某个动作的请求。当一个对象收到发给自己的消息的时候,则调用消息中指定的操作。对消息的处理可能会改变对象的状态。可以认为,消息的传递大致等价于面向过程方法中的函数调用。

下面简要地介绍面向对象的应用开发过程。

(1)分析阶段。在分析中,需要找到特定对象,根据对象的公共特征把它们组成集合,直到最后能够标识出对这个问题的一个抽象为止。另外,还要标识出应用系统的结构中对象之间的联系。

(2)高层设计。在这一阶段,应该设计应用的顶层视图,这相当于开发一个表示系统的类的界面。

(3)类的开发。应用设计阶段基本上是类的开发,一个应用可以抽象成用一个类表示,也可以分成几个类。这一阶段将标识对各个类的要求,并给出类的定义。

(4)实例化。建立类的实例——对象,这些对象对应于在分析阶段所标识的实体。另外,还需要建立实例之间的通信通道,实现对象与对象之间的联系。在这一阶段,所有的问题都要得到最终的解决。

(5)组装测试。首先进行类的测试,类的封装特性使得能在单个类中调试一个代码过程,而不会影响其他的类。随后把系统组装成一个完整的应用来进行测试。

(6)应用的维护。应用的维护包括在系统的操作中定位故障,在现有的系统中加入新的行为等。

1.2.5 Rational统一过程

Rational统一过程(Rational Unified Process RUP)是一种软件工程过程。RUP吸收了许多开发模型的优点,具有很好的可操作性和实用性,一经推出,就迅速得到业界的广泛认可。

RUP有一个著名的二维结构图,如图1.2.3所示,该图显示了全部RUP的构架。

(1)水平轴代表时间,显示了过程的生命周期,包括初始(Inception)、细化(Elaboration)、构造(Construction)、移交(Transition)4个阶段。

(2)竖直轴代表核心过程工作流,包括业务模型(Business Modeling)、需求(Tequirements)、分析和设计(Analysis&Design)、实现(Implementation)、测试(Test)、实施(Deployment)、配置和变更管理(Configuration&Change Management)、项目管理(Project Management)、环境(Environment)。

35208-00-023-1.png

图1.2.3

在前面我们已经提到过关于软件危机的一些内容。随着软件产业的快速发展,在软件开发过程中暴露出的问题也越来越多。人们经过多年来的实践和探索,总结出了软件开发过程中一些优秀的方法(实践活动),这些方法已经被证明能够较好地解决软件开发过程中的根本问题。RUP之所以广泛流行,原因是它将这些最佳软件开发方法以一种适当的形式结合起来。下面将介绍这些优秀的方法,以及它们是如何在RUP中得到贯彻执行的。

(1)迭代的开发软件。迭代方法是RUP推荐的方法。RUP的每个阶段可分为一到多个迭代周期。软件迭代开发是一个连续的发现、创造和实现的过程。每一个迭代过程,都是一个完整的开发循环,产生一个可执行的产品版本,该产品可能是一个阶段性的产品,如果这次迭代过程是最后一次开发过程,则该产品就是最终产品。迭代开发的好处在于它能够尽早地发现需求、设计和实现中的不一致,能够尽早地发现遗留问题并快速地解决,能够在整个项目生命周期中更加平均地分配开发组的工作量。图1.2.4演示了在RUP中的软件迭代开发过程。

35208-00-023-2.png

图1.2.4

(2)需求管理。需求管理的难点在于需求的动态性:需求在整个软件的生命周期中是不断变化的。软件开发人员在开始开发系统之前不可能完全地说清楚一个系统的真正需求,除非这个系统非常简单。动态需求管理主要包括:提取系统的功能和约束,并写成文档;估计需求的变化并评估需求变化所产生的影响;详细记录根据需求变化所做出的每一项决定。

(3)应用基于构件的构架。狭义来说,软件构件是指可复用的、提供明确接口完成特定功能的程序代码块。软件构件是软件、模块、包或子系统的一个重要部分。我们可以把构件想象成硬件系统里的一个个“零件”。构件可以独立开发(需求分析、设计、编码、测试)、部署和发布。构件是一个高内聚的软件包,通过接口对外交互,屏蔽了内部实现细节,它可通过独立开发封装为符合业界认可的模型标准的二进制代码。

构架描述了某个物体的多个部分如何集成为一个整体。如:一架飞机有一个构架;我们这本书也有一个构架。

基于构件的开发是一种非常重要的软件构架方法。构件使重用成为可能。基于构件的系统由3部分组成:已存在的部件,现成的由第三方提供的部件和标识此特殊领域的新部件。在这3部分中,只有最后一个部分需要软件开发人员去开发设计。如果结合迭代开发软件的实践,那么随着系统需求的不断细化或变化,使用基于构件的构架也在不断演变。每个迭代过程都产生一个可执行的构架,开发人员和客户可以以系统需求为标准度量,测试此构架。这种方法能够使开发小组不断地发现问题和解决问题。

RUP提供了一个设计、开发、验证构架的系统性的方法。它还提供了一个模板,用以描述建立在多重构架视图概念基础上的构架。

(4)建立可视化模型。建立模型是因为我们无法完全清晰地理解一个复杂的模型。可视化建模可以帮助开发人员将一个系统的结构和行为可视化、具体化,并以文档的形式记录下来。一个项目组中的各个组成人员可以利用建好的模型清晰地无二义地与其他人员交流他们的想法。

RUP很大部分是在开发过程中开发和维护系统模型,它可以指导我们如何有效地使用UML建模,包括告诉我们需要什么样的模型,为什么需要这些模型和如何建造这些模型。

(5)不断地验证软件质量。在完成软件实施后再去查找BUG并修正,要比在早期就进行这项工作花费更多的费用。因此,当迭代地开发软件时,在每次迭代过程中都进行细致的测试是非常必要的。

RUP非常重视验证和客观评价产品是否达到了预期的质量水平,测试工作贯穿整个软件开发生命周期中:我们可以测试早期系统原型的主要功能;也可以测试构架的稳定性和性能;还可以测试最终产品。

(6)配置管理和变更管理。在开发生命周期中会产生很多有用的制品。在迭代开发过程中,这些制品一次一次地进化和更新。项目组必须跟踪产品的进化,捕获并管理对于变更的请求,然后通过一些方式实现变更。

迭代开发软件密集型系统时,面临的巨大挑战是必须安排不同组的开发人员同时工作于多个迭代过程、发布版本、产品和平台中。如果没有严格的软件变更控制,开发就会陷入混乱之中。

RUP是如何表述的呢?RUP包含了4种重要的模型元素。

(1)工作人员。工作人员定义了个人或作为群组一起工作的人们的行为和职责。在软件开发过程中,常见的工作人员有:系统分析员、设计师、测试师等。需要注意的是,不要把工作人员当成软件开发过程中的某一个具体的人,而应该当成某一类角色,每类角色有相同行为并担当相同的职责。

(2)活动。活动定义了工作人员可以执行的工作。每个活动都被分配给特定的工作人员。

(3)制品。制品是项目中有形的产品。工作人员把制品当做执行一项活动的输入,同时这个活动的输出也是制品。模型、文档、源代码、可执行文件等都可以被认为是软件开发过程中的制品。

(4)工作流。工作流用来描述有重要意义的活动序列,并表示出工作人员之间的相互作用。在UML术语中,一个工作流可以表示为协作图、顺序图或活动图。

小结

本节我们主要学习了以下知识。

1. 软件

软件是计算机系统中与硬件相互依存的另一部分,它是包括程序、数据及其相关文档的完整集合。

软件的主要特点有:①软件是被开发或设计的,而不是被制造的;②软件不会“磨损”,但会“退化”;③软件的开发至今尚未摆脱手工艺的开发方式;④软件是复杂的。

2. 软件工程

因为软件危机的出现,人们才开始用工程化的思想来管理软件开发。软件工程是指:将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件。在软件工程这一部分里,我们重点讲述了软件生命周期和软件生存期模型。软件生存期的6个步骤是:①计划;②需求分析和定义;③软件设计(详细设计);④编码;⑤软件测试;⑥维护。常见的软件生存期模型有瀑布模型和原型实现模型等。因为UML最早是为了描述面向对象建模方法而出现的,所以我们也介绍了面向对象软件工程方法。

3. RUP

RUP综合了许多最佳的现代软件开发方法(实践),这些方法有:①迭代的开发软件;②需求管理;③应用基于构件的构架;④建立可视化模型;⑤不断地验证软件质量;⑥配置管理和变更管理。