面向对象分析(Object-Oriented Analysis,OOA),就是运用面向对象方法进行系统分析。它是软件生命周期的一个阶段,具有一般分析方法所共同具有的内容、目标及策略。但是OOA强调运用面向对象方法,对问题域和系统责任进行分析与理解,找出描述问题域和系统责任所需要的对象,定义对象的属性、操作以及对象之间的关系,目标是建立一个符合问题域、满足用户需求的OOA模型。
OOA对问题域的观察、分析和认识是很直接的,对问题域的描述也是很直接的。它所采用的概念与问题域中的事物保持了最大程度的一致,不存在语言上的鸿沟。问题域中有哪些值得考虑的事物,OOA模型中就有哪些对象,而且对象、对象的属性与操作的命名都强调与客观事物一致。另外,OOA模型也保留了问题域中事物之间关系的原貌。
面向对象分析与面向对象设计(Object-Oriented Design,OOD)的职责是不同的。在OOA阶段要用面向对象的建模语言对系统要实现的需求进行建模。OOA不考虑与系统的具体实现有关的因素(例如采用什么编程语言、图形用户界面和数据库等),从而使OOA模型独立于具体的实现环境。OOD则是针对系统的一组具体的实现条件,继续运用面向对象的建模语言进行系统设计。其中包括两方面的工作,一是根据实现条件对OOA模型做某些必要的修改和调整,作为OOD模型的一个部分;二是针对具体实现条件,建立人机界面、数据存储和控制驱动等模型。
自从软件工程学问世以来,先后出现过多种分析方法。各种分析方法从不同的观点提出了认识问题域并建立系统模型的理论与技术,使软件开发走上了工程化和规范化的轨道。然而,分析工作仍然面临着许多难题。随着时代的发展和科技的进步,人们对软件的要求越来越高,分析所面临的问题也越来越突出。主要的问题包括:对问题域和系统责任的正确理解、人与人之间的正确交流、如何应对需求的不断变化以及软件复用对分析的要求。
1. 问题域和系统责任
在过去的几十年中,人们都认为大规模的软件开发是一项冒险的活动。人们之所以这么认为,其根本原因在于软件的复杂性,而且这种复杂性还在不断地增长。
软件的复杂性首先源于问题域(problem domain)和系统责任(system responsibility)的复杂性。
问题域 :被开发系统的应用领域,即在现实世界中这个系统所涉及的业务范围。
系统责任 :被开发系统应该具备的职能。
这两个术语的含义在很大部分上是重合的,但不一定完全相同。例如,要为银行开发一个金融业务处理系统,银行就是这个系统的问题域。银行的日常业务(如金融业务、个人储蓄、国债发行和投资管理等)、内部管理及与此有关的人和物都属于问题域。尽管银行内部的人事管理属于问题域,但是在当前的这个系统中它并不属于系统责任。像对计算机信息的定期备份这样的功能属于系统责任,但不属于问题域。图2-1是对本例的一个图示。
图2-1 问题域与系统责任示例
图2-1中,左边的椭圆所示的范围为问题域部分,右边的椭圆所示的范围为系统责任部分,二者之间有很大的交集。
对问题域和系统责任进行深入的调查研究,产生准确透彻的理解是成功地开发一个系统的首要前提,也是开发工作中的第一个难点。这项工作之所以困难是由于以下原因:
·软件开发人员要迅速、准确、深入地掌握领域知识。
俗话讲,隔行如隔山。要开发出正确而完整的系统,就要求软件开发人员必须迅速地了解领域知识,而不能要求领域专家懂得全部的软件开发知识。这对软件开发人员来说是一个挑战。不但如此,分析员对问题域的理解往往需要比这个领域的工作人员更加深入和准确。许多领域的工作人员长期从事某一领域的业务,却很少考虑他们司空见惯的事物所包含的信息和行为,以及它们如何构成一个有机的系统。系统分析员则必须透彻地了解这些。此外,软件开发人员还要考虑如何充分发挥计算机处理的优势,对现实业务系统的运作方式进行改造,这需要系统分析员具有比领域专家更高明的见解。这是因为许多系统的开发并不局限于简单地模拟问题域中的业务处理并用计算机代替人工操作,还要在计算机的支持下,对现行系统的业务处理方式做必要的改进。
·现今的系统所面临的问题域比以往更为广阔和复杂,系统比以往更为庞大。
随着计算机硬件性能的提高和价格的下降,以及软件技术的发展使得开发效率的不断提高,人们把越来越多、越来越复杂的问题交给计算机解决。相对而言,问题域和系统责任的复杂化对需求分析的压力比其他开发阶段更为巨大。
OOA强调从问题域中的实际事物以及与系统责任有关的概念出发来构造系统模型。这使得系统中的对象、对象的分类、对象的内部结构以及对象之间的关系能良好地与问题域中的事物相对应。因此,OOA非常有利于对问题域和系统责任的正确理解。
2. 交流问题
如果分析阶段所产生的文档使得分析员以外的其他人员都难以读懂,那就不利于交流,随之而来的是各方对问题的理解会产生歧义。这会使彼此的思想不易沟通,并容易隐藏许多错误。对软件系统建模涉及如下人员之间的交流:
·开发人员与用户及领域专家间的交流。为了准确地掌握系统需求,双方需要采用共同的语言来理解和描述问题域。以往多采用自然语言描述需求,效果并不理想。
·开发人员之间的交流。分析人员在系统建模时经常需要分工协作,对问题要进行磋商,并要考虑系统内各部分的衔接问题。分析人员与设计人员之间也存在着工作交接问题,这种交接主要通过分析文档来表达,也不排除口头的说明和相互讨论。这些要求所采用的建模语言和开发方法应该一致,且不要过于复杂。
·开发人员与管理人员之间的交流。管理人员要对开发人员的工作进行审核、确认、进度检查和计划调整等。这就需要有一套便于交流的共同语言。这里“语言”是广义的,它包括术语、表示符号、系统模型和文档书写格式等。
OOA充分运用人类日常活动中采用的思维方法和构造策略来认识和描述问题域,构造系统模型,并且在模型中采用了直接来自问题域的概念。因此,OOA为改进各类人员之间的交流提供了最基本的条件——共同的思维方式和共同的概念。
3. 需求的不断变化
社会的发展是迅速的,这就要求软件系统也要不断地随之变化。此外,客户的主客观因素、市场竞争因素、经费与技术因素,都会影响需求的变化。显然,软件开发者必须以合作的态度满足用户需求。于是系统的应变能力的强弱,便是衡量一种分析方法优劣的重要标准。那么,系统中哪些因素是容易变化的?哪些因素是比较稳定的?人们在实践中发现:当需求发生变化时,系统中最容易变化的部分是功能部分(对OO方法而言则是对象的操作或操作的协作部分);其次是对外的接口部分;第三是描述问题域事物的数据(对OO方法而言即对象的属性);相对稳定的部分是对象。
OOA之所以对变化比较有弹性,主要是获益于封装和信息隐蔽原则。它以相对稳定的成分(对象)作为构成系统的基本单位,而把容易变化的成分(属性及部分操作)封装并隐藏在对象之中,它们的变化主要影响到对象内部。对象只通过接口对外部产生有限的影响。这样就有效地限制了一处修改处处受牵连的“波动效应”。从整体范围看,OOA以对象作为系统的基本构成单位,对象的稳定性和相对独立性使系统具有一种宏观的稳定效果。即使需要增加或减少某些对象,其余的对象仍能保持相对稳定。
4. 软件复用的要求
软件复用是提高软件开发效率、改善软件质量的重要途径。20世纪80年代中期以前的软件复用,主要着眼于程序(包括源程序和可执行程序)的复用。到20世纪80年代末期,人们已开始提出对软件复用的广义理解,注意到分析结果和设计结果的复用将产生更显著的效果。分析结果的复用是指把分析模型中的可复用部分用于多个系统的开发,并要求一个分析模型可在多组条件下予以设计与实现。此外,还可以在把一个老系统改造为基于新的软硬件支持的新系统时,尽量地复用旧的分析结果。
OO方法的继承本身就是一种支持复用的机制,它使特殊类中不必重复定义一般类中已经定义的属性与操作。无论是在分析、设计,还是编程阶段,继承对复用带来的贡献都是显而易见的。
由于OOA模型中的一个类完整地描述了问题域中的一类客观事物,并且它是独立的封装实体,它很适合作为一个可复用成分。由一组关系密切的类(如具有一般—特殊结构、整体—部分结构或一组相互关联的类)可以构成一个粒度更大的可复用成分。在OO开发中,先在OOA阶段建立的是一个符合问题域、满足用户需求的OOA模型,然后再根据具体实现条件进行系统设计,这样针对一个分析模型可有多个实现,使得OOA结果能够通过复用而扩展为一个系统族。
系统分析就是研究问题域,产生一个满足用户需求的系统分析模型。这个模型应能正确地描述问题域和系统责任,使后续开发阶段的有关人员能根据这个模型继续进行工作。
自软件工程学问世以来,已出现过多种分析方法,其中有影响的是功能分解法、数据流法、信息建模法和20世纪80年代后期兴起的面向对象方法。前三种分析方法在历史上发挥过应有的作用,用它们也建立过许多成功的系统,直到今天仍然被一些开发者所采用。我们在谈到这些方法的缺点时不是要否定它们,而是针对具体问题进行讨论。应该指出,面向对象的分析正是在许多方面借鉴了以往的分析方法。
面向对象的分析,强调用对象的概念对问题域中的事物进行完整的描述,刻画事物的性质和行为,同时也要如实地反映问题域中的事物之间的各种关系,包括分类关系、组装关系等静态关系以及动态关系。
自20世纪80年代后期以来,相继出现了多种流派的OOA及OOD方法。各种方法的共同点是,都基于面向对象的基本概念与原则,但是在概念与表示法、系统模型和开发过程等方面又各有差别。统一建模语言UML的出现,使面向对象建模概念及表示法趋于统一。我国的软件行业标准“面向对象的软件建模规范——概念与表示法”就是参照UML制定的。下面分别阐述在OOA阶段本书所使用的概念与表示法、OOA模型及过程指导。
1. 概念与表示法
在OOA阶段所使用的概念包括对象、属性、操作、类、继承、聚合和关联等,这些概念属于UML的核心内容,且表示法也是相一致的。
2. OOA模型
OOA模型就是通过面向对象的分析所建立的系统分析模型,表达了在OOA阶段所认识到的系统成分及彼此之间的关系。在可视化方面,用建模概念所对应的表示法绘制相应种类的图。
目前的各种OOA方法所产生的OOA模型从整体形态、结构框架到具体内容都有较大的差异。OOA模型的差异集中地体现在各种方法所强调的重点和主要特色方面。一般来说,各种方法只把它认为最重要的信息放在模型中表示,其他信息则放到详细说明中,作为对模型的补充描述和后续开发阶段的实施细则。
图2-2所示的OOA模型是按照图加相关文档这种方式组织的。在第14章要对模型和图进行详细阐述。
图2-2 OOA模型
使用用况图来捕获与描述用户的要求,即系统的需求,从而建立系统的需求模型(用况模型)。尽管有关建立用况模型的内容并不是面向对象的,但在UML中详细地规定了这方面的内容,且用况模型已经被人们普遍地接受,因而本书把建立用况模型的有关知识和技术放在OOA中讲述。按照某些做法,也可以在OOA之前利用用况模型对系统的需求进行捕获与描述。在开发系统时,上述两种做法是不矛盾的,这只是一个阶段划分问题。
用类图构建的模型是系统的基本模型,主要是因为类图为面向对象编程提供了最直接的依据。基本模型为系统的静态模型,它描述系统的结构特征。类图的主要构成成分是:类、属性、操作、泛化、关联和依赖。这些成分所表达的模型信息可以从以下三个层次来看待:
·对象层:给出系统中所有反映问题域与系统责任的对象。用类符号表达属于一个类的对象的集合。类作为对象的抽象描述,是构成系统的基本单位。
·特征层:给出每一个类(及其所代表的对象)的内部特征,即给出每个类的属性与操作。该层要以分析阶段所能达到的程度为限给出类的内部特征的细节。
·关系层:给出各个类(及其所代表的对象)彼此之间的关系。这些关系包括泛化、关联和依赖。该层描述了对象与外部的联系。
概括地讲,OOA基本模型的三个层次分别描述了:1)系统中应设立哪几类对象;2)每类对象的内部构成;3)每类对象与外部的关系。三个层次的信息(包括图形符号和文字)叠加在一起,形成完整的类图。
按照UML的做法,可以建立对象图,以作为类图的补充。
为建立系统的行为模型,需要建立交互图、活动图或状态机图。交互图主要有两种形式:顺序图和通信图,每种形式强调了同一个交互的不同方面。顺序图表示按时间顺序排列的交互,通信图表示围绕着角色所组织的交互以及角色之间的链。与顺序图不同,通信图着重表示扮演不同角色的对象之间的连接。活动图展示从活动到活动的控制流和数据流,通常用于对业务过程和操作的算法建模。状态机图展示对象在其生命周期内由于响应事件而经历的一系列状态,以及对这些事件做出的反应。
包图用于组织系统的模型,其中的包是在模型之上附加的控制复杂性的机制。通过对关系密切的元素进行打包,有助于理解和组织系统模型。
相对基本模型来说,系统的行为模型和用包图建立的系统组织模型,都作为系统的辅助模型。
以图的方式建立模型是不够的。对各种图中的建模元素,还要按一定的要求进行规约(即详细描述)。通过用图表示的模型加上模型规约的方式,构成完整的模型。有关模型规约的具体格式,参见附录B。
3. OOA过程
各种OOA方法一般都要规定一些进行实际分析工作的具体步骤,指出每个步骤应该做什么以及如何做,并给出一些启发策略,用以告诉使用者对各种情况应该怎样处理以及从哪些方面去思考能有助于实现自己的目标。
现在还没有关于面向对象的软件建模过程指导方面的国际规范,各种OOA方法在建立模型的过程方面都有差别,且详简也有所不同。本书所使用的建模过程指导,是从由数十家高校、科研院所和软件企业参加的国家重点科技攻关计划“青鸟工程”所研发的面向对象软件开发规范中总结出来的,图2-3给出了其具体内容。
图2-3 OOA过程模型
图2-3给出的是OOA过程模型,其中只给出了过程中的活动,而没有展示过程角色和资源等因素。图中的箭头表明建模活动是可以回溯的,也可以交替进行。例如,在发现了一些(并非全部)对象之后,就可以开始定义它们的属性与操作;此时若认识到某些关系,可以及时建立这些关系;在建立关系时得到某种启发,联想到其他对象,又可及时转到发现对象的活动。在CASE工具的支持下,各种活动之间的切换可以相当灵活。有些软件开发组织习惯于规定一个基本的活动次序,使OOA过程按这种次序一步一步地执行,这也是可以的。其实各软件开发组织应该依据或参照经过检验的开发过程,建立适合自己需要的开发过程。
以下是对实施OOA过程的几点建议:
1)把建立需求模型放在分析工作的开始。通过定义用况和建立用况图来对用户需求进行规范化描述。
2)把建立基本模型的三个活动安排得比较接近,根据需要随时从一个活动切换到另一个活动。
3)建立交互图、状态机图或活动图的活动可以安排在基本模型建立之后,但也可以与基本模型的活动同时进行,即在认识清楚了若干对象后,就开始绘制反映系统动态行为的模型图。
4)建立模型规约的活动应该分散地进行,结合在其他活动之中。最后做一次集中的审查与补充。
5)原型开发可反复地进行。在认识了基本模型中一些主要的对象之后就可以做一个最初的原型,随着分析工作的深入不断地进行增量式的原型开发。原型开发的工作还可以提前到建立需求模型的阶段进行。在开发的早期阶段建立的原型,主要用于捕获与证实用户的需求。
6)在分析较小的系统时可以省略划分包的活动,或把该活动放在基本模型建立之后进行。在分析大中型系统时,可以按需求先划分包,根据包进行分工,然后开始通常的分析;在分析的过程中,若需要仍可以用包来组织模型元素。
1. 简述OOA模型及OOA过程。
2. 为什么要进行OOA?
3. 简述问题域与系统责任间的关系。
4. OOA是如何应对需求变化性的?
5. 为什么把用类图构建的模型称为基本模型?
6. 你对本章讲述的分析面临的主要问题有过什么实际感受?请举例说明。