3 面向对象的分析方法
面向对象分析
作为一个比较全面的方法,面向对象分析由五个主要步骤组成,即确定类与对象,识别结构,识别主题,定义属性和定义方法。一旦建立了模型,就可以由五个层次来表示,它们是:
主题层 主题给出分析模型的总体概貌。
对象层 对象是数据及其处理的抽象。它反映了系统保存和处理现实世界中某些事物的信息的能力。
结构层 结构表示问题域的复杂性。类—成员结构反映了一般——特殊关系,整体——部分结构反映了整体和部分的关系。
属性层 属性就是数据元素,可用来描述对象或分类结构的实例,可在图中给出并在对象的存储中定义。
方法层 方法是在收到消息后必须进行的处理,在图上定义它并在对象的存储中指定。
一,确定类与对象
1、什么是类、对象
在面向对象分析中对象是一个封装体和抽象体,即是属性和处理这些属性的方法的封装体以及问题域的抽象体。类是对一个以上对象的共同属性和方法集合的描述,包括如何在一个类中建立新对象的描述。
属性以及处理这些属性的方法的封装体对面向对象分析模型的稳定性影响很大。首先,封装性是可以将属性和方法看成一个不可分割的整体的基础。第二,封装性有助于减少重复劳动。
在面向对象分析中,对问题域中某件事情的抽象是很重要的。事实上,在每次分析活动中,分析人员必须首先理解要分析的问题域。而将对象定义为现实世界的抽象,这样有助于深刻理解问题域,从而获得系统模型。这种模型至少可以产生一个现实的 可观察且可管理的模型层集合,包括主题、对象、结构、属性和方法。
系统模型还为上下文的初始表示奠定了基础。上下文树是由系统分析人员在分析过程中画出来用于技术决策的。系统上下文表明该系统包含有几个问题域、要保存什么样的数据、处理的复杂程度如何等。系统上下文有着“四重约束”,即预算、进度、性能和人员。为了使一个项目顺利进行,必须满足所有这四个约束。
2、为什么要识别对象
识别对象的主要目的是为了使一个系统的技术表示同现实世界更为接近。这种分析的表示和策略是依据人类的3种基本分析方法的,即对象和属性,类与成员,以及整体和部分。
识别对象的另一个目的是希望建立考察问题领域和了解需求的稳定框架。对象只是相对稳定的,但分析问题的框架却是稳定的。
最后一个动机是希望在从系统分析向系统设计过渡时不要改变所采用的表示法。如多年来在分析中使用的是网络组织(数据流程图),而在设计中使用的则是层次组织(结构图)。这一状况使开发者感到十分不便,无法跟踪开发过程。为此可以通过在分析、设计和实现三个阶段均采用面向对象的表示法来改进这一局面。
3、如何定义对象。
(1)、表示法
类-&-对象 类
(2)何处去确定对象
问题域、文字说明和图形表示都是有助于确定对象的素材。
首先应该观察问题域并研究问题域本身。问题域是用户的世界,用户一般在问题域中给出或隐含地给出某种形式的需求,这些需求可能是几句话的描述,也可能是大段的叙述。
其次是研究文字说明材料。让用户提供一个详细的专题报告,并从专业书籍中找到该问题域的权威描述,这种方法有助于了解某个专题的基本知识和术语,同时这样一种调研也可尽快掌握问题域的概貌。在阅读时,重点注意名词,但不能简单地把这些名词声明为对象。
最后是要仔细地观察各种图形表示。收集所能拿到的任何图形表示,包括方块图、接口图、系统部件图和高层次的数据/控制流程图等,并用图符和它们之间的连线的方式画出问题域的草图。
(3)哪些可以作为对象
为了确定潜在的对象,需要首先确定问题域的结构、有关系统、装置、所记忆的事件、所起的作用、地点和组织机构。下面按其用途的大小不依次考虑这些问题。
结构。 问题域中的结构对确定对象和表示问题域层十分重要。在面向对象分析中,有专门的一个识别结构的步骤。在结构当中,最为重要的就是泛化——特化结构和整体——部分结构(后面详细叙述)。
有关系统。 所考虑的系统将以何种方式同有关的系统和外部终端交互?如无线或者是有线。
装置。 所考虑的系统需要同何种装置进行交互(交换数据和控制信息)。要注意的是不要从实现上而应从功能上来考虑,以便出在具体实现变化时,无须作太多的重复性劳动。
应记忆的事件。 系统是否有必要观测和记录时间点和历史事件。
人所起的作用。 在所考虑的系统中,人起什么作用?代表人的对象有两种:系统用户;并不与系统直接交互,但系统有其记录的人。他们在系统中起的作用不同,后面的属性和方法的探讨将更详细地揭示这种区别。
地点。 所考虑的系统需要什么样的地理知识?
组织结构。 人属于哪个机构?
(4)应考虑那些内容
假设已经找到一个候选对象,这时又发现另一个可能成为对象的东西,那么是否应该将它作为对象放到模型中去?这时应该考虑以下问题:
①必要的记忆(属性)
是否该系统需要记忆某个对象的所有情况?能否描述该对象的实例?该对象潜在的属性是什么?是否真实事物的知识对所考虑的系统有用?是否系统需要记忆与该对象有关的情况?如果一切的回答是否定的,则该对象存在的合法性和必要性就值得怀疑。记住:现实世界中存在许多对象,但仅可以讨论而已,不能都纳入系统中去。
②必要的方法系统是否需要该对象提供的方法?只要必要的记忆中所述的不完全是否定的,则也必定需要方法,因此最低限度也要维持该对象的一次出现,即有一个合适的对象。
有时某个对象可能要求有方法,但不要求有记忆(属性)。如可能在问题域中找到一个“用户”对象,但系统并不要求保存该用户的任何信息,但是系统确实需要监视用户、响应请求和定时提供信息。因此由于需要方法,不得不将一个相应的对象加到问题域的模型中去。
③一个以上的属性。在分析人员考虑不周的地方,该准则能帮助他筛选潜在的对象。如果一个对象(如“地点”)有一个名字相同的属性,就让人费解。这时“地点”最好作为属性用到其他的对象中去,而不是单独作为一个对象。
关键是要详细到何种程度:对象是用属性来描述的,而属性则又可在属性字典中描述。
④共同属性。能否识别一组每个对象都有的属性?每次当系统产生一个对象时,它应该为所有的共同属性赋值。如果只有部分属性可用,则表明还存在一个泛化——特化结构(后面讨论)。
⑤共同的方法。能识别一组共同的方法吗?即可用到某个对象的所有实例的处理操作。这些处理操作可能用来创建对象的实例,在对象之间建立联系。如果每个实例的方法都是相同的,那还好办。但是如果方法是随实例的类型而变化的,则表明还存在一个泛化――特化结构。
⑥基本需求。基本需求是指那些系统必须具备的要求,如在考虑“雷达”和“传感器”对象时,不管最终采用何种计算机技术,最终的目标还是“雷达”和“传感器”对象。至于其他的都只是设计和实现上的考虑。
(5)对什么提出否定意见
①并非必要的记忆;
②并非必要的方法;
③单个实例;
④冗余信息。
首先,如果系统并不需要保存某个对象的信息也不需要为它提供方法,则去掉该对象。这种情况在同用户讨论和评价初始模型时经常发生。
其次,对只有单个实例的对象提出异议。当然如果某个(只有单个实例的对象)确反映了问题域的真实情况,则不必管它。
最后,考虑冗余信息的模型。在基本需求模型中,冗余信息会使一切变得十分繁杂混乱。因此尽量少地保存属于冗余信息的派生结果。
(6)如何命名对象原则上,对象名应该能描述对象的实例的基本特征,因此,为对象命名的主要方法可以是:
①用单个名词或者形容词加名词作为对象名;
②采用标准名称作为对象名;
③尽量采用可读性好的名字。
二、识别结构
本节研究泛化——特化结构和整体——部分结构。
1,什么是结构
在面向对象分析中,结构是问题域复杂关系的表示,它与系统的任务直接相关。结构有一般——特殊结构和整体——部分结构。它们是面向对象分析方法和重要组成部分。
2、为什么要定义结构
泛化—特化结构和整体—部分结构能使分析人员和领域专家的注意力集中在具有多个类和对象的复杂问题上。也可以考虑到问题的边缘,揭示那些尚未发现的类和对象。此外,泛化—特化结构具有继承性,泛化类和对象的属性和方法一旦被识别,即可在特化类和对象中使用。
3、如何定义结构
(1)如何定义泛化——特化结构首先给出泛化——特化结构的表示法和策略,然后给出它的层次
①表示法泛化——特化结构用下图表示:顶部是一个泛化类,下面是几个特化类,它们之间用线连接。一个半圆型的标记表明图形泛化——特化结构这种表示法是有向的,从半圆弧中心画一条线所指的是泛化类。一般来说,泛化类总是放在上部,而特化类放在下部。
泛化——特化结构线的端点位置表明这是类(而不是对象)之间的映射。
每个特化类的名字必须能充分地反映它自己的物征。比较合适的特化类名字可由相应的泛化类名加上能描述该特化类性质的形容词来组成。如对于名为Sensor(传感器)的泛化类,其特化类可称为StandardSensor (标准传感器)或CriticalSensor (精密传感器)而不称为Critical(标准)。
所有最底部的特化类必须使用“类—&—对象”符号,而其他地方即可用“类—&—对象”符号也可用类符号。如下图所示的实例。
②定义一般——特殊结构的策略
将每个类看成一般类。针对它的潜在特殊类提出以下问题:
a、它是属于该问题域吗?
b、它是该系统的任务吗?
c、存在继承性吗?
d、特殊类满足类—&—与对象的准则吗?
以类似的方式,将每个类考虑为特殊类,并对它的潜在泛化类提出同样的问题。尤其是与以前类似问题的面向对象分析结果比较来寻找可以直接重用的泛化——特化结构并吸取有关教训。如果存在许多特化类,则首先考虑最简单的和最复杂的特化类,然后处理其他的。如考虑对象“飞机”,它可以按不同的分类方式来进行特化:
军用和民用,喷气和普通,固定机翼与可变机翼,商用和私人,在航行中的和在地面上的。
在每一种情况下,查看潜在的属性和方法。检查特化对象之间的区别;同时检验它们是否是真实的特化类。如汽车和飞机。另外还要考虑是否该特化类属于该问题域。
其次,将某个类看作特化类。那么,是否从该问题域中的其他类就能找到一个泛化类,且它能表示共同的属性、方法或两者呢?是否泛化对象反映了真实的泛化?是否泛化对象本身仍在问题域的范围内?
采用继承来显式表达属性和方法的共同部分,可以实现在一般 特殊结构中恰当地分配 属性和方法。将共同的属性和方法放在上层,而将特有的属性和方法放在下层。
泛化——特化结构的准则之一就是它是否反映了问题域中的泛化——特化关系。
③层次与网络每个一般特殊结构均形成层次或网络。在实践中,泛化——特化结构的最普通形式就是层次(如下图所示)。
在本例中,Person (人)是Owner(所有者)、或Clerk(工作人员)或是一个Clerk兼Owner,这一层次的特化类中就存在着一些冗余信息。
借助于泛化——特化网络还可以研究其他问题域的持化类,而且还可以显式地表示更多属性和方法的公共部分。
下图中的例子表明在某个问题域中的Person是一个Owner、一个Clerk或两者。特化类OwnerClerkPerson描述了一个有着多重直接泛化类的类,它表明一个对象继承了来自其祖先的属性和方法。而且如果这个类本身还有属性和方法,则它们将出现在特化类OwnerClerkPerson中。
因此,网络能描述复杂的特殊类;能有效地表示公共部分;对模型的复杂程度影响较少。
随着特化类的增加,网络结构将变得非常复杂。此时可考虑将网络的某一部分重新组合为另一个层次。同时要注意到在一个以上的直接泛化类中使用相同的属性名会导致类—&—对象规范的严重混乱。
泛化——特化结构网络可以表示两个不同泛化——特化结构的重叠或者组合(如下图所示)。
(2)、如何定义整体—部分结构在面向对象分析中,整体——部分关系对于在问题域和系统任务的边界区域中识别类—&—对象是非常有用的。同时它还能将具有特殊的整体——部分关系的类—&—对象组织到一起。
①表示法整体——部分结构可用下图表示:在顶部是一个整体对象(用类—&—对象符号表示的对象),下部是部分对象(用类—&—对象符号表示的对象),它们之间用线(结构线)连接。三角标记表明这是整体——部分结构。这种表示法是有向的。将整体放在上部而将部分放在下部可以使模型便于理解。根据该模型,整体可有多个部分,也可有不同种类的部分。整体——部分结构线的终点位置反映了对象之间(而不是类之间)的映射。整体——部分结构线的每一端都标有一个量或区域,它表示该整体拥有的部分数。
在下图所示的例子中,Aircraft是一个整体,它可能:没有Engine;最多有四台Engine。并且Engine是一个部分,它可能:不是Aircraft的一部分;至多是一架Aircraft的一部分。
②策略策略由两部分组成,一部分是确定什么,另一部分是考虑什么。
a、确定什么当确定潜在的整体——部分结构时,考虑以下的变种情况:
总成 —— 部件
容器 —— 内容
集合 —— 成员此外,还应查看从前相同和类似问题的面向对象分析结果。确定能直接重用的整体——部分结构,并吸取有关的教训。
现在考虑整体——部分结构的变种。如下图,一架Aircraft是一个总成,而Engine则是该总成的部件。
如下图,如果将Aircraft考虑成一个容器,则Pilot(飞行员)就是容器中的内容。
如下图,如果将FlightSegment(飞行段)看成是成员,则FlightPlan(飞行计划)就是它们中的“有序”集合。
该“有序”约束可在整体的类—&—对象规范中指定。
如下图领域专家运用集合——成员关系(思维模型)来分析复杂问题(如下图)。
b、考虑什么
在将每个对象看成整体的前提下,针对它的潜在部分,考虑下列问题:
是否属于该问题域?
是否属于该系统的任务?
所反映的是多个状态值吗?
是否提供了有价值的抽象?
同样,在将每个对象看成部分的前提下,对每个潜在的整体考虑同样的问题。
(3)多重结构多重结构包括泛化——特化结构、整体——部分结构或两者的各种组合结构。多重结构通常是自顶向下的,但有时也可用实例连接来依次映射。
三、识别主题
1、什么是主题
在面向对象分析中,主题是一种知道读者或用户研究大型复杂模型的机制。在初步面向对象分析的基础上,主题有助于分解大型项目以便建立工作小组。
主题所提供的机制可控制一个用户必须同时考虑的模型数目。同时它还可以给出面向对象分析模型的总体概貌。
主题所依据的原理是整体—部分关系的扩充。因此,识别主题的主要基础是以泛化——特化结构和整体——部分结构为标志的问题复杂性。在这种方式下,主题就是用来同整个问题域和系统任务这个“总体”进行通讯的“部分”。
为什么要识别主题真实系统有着大量的对象和结构。任何方法及其应用是否成功的一个重要标志就是它应该提供好的通信条件以避免分析人员和用户的信息过量。
人类的短期记忆能力限于一次记忆5—9个对象。这就是著名的7加减2原则。面向对象分析从控制可见性和指导读者的注意力这两个方面来贯彻这一原则。
首先通过控制分析人员能见到的层次数目来控制可视性;如在分析的5个层次中,读者可选择只看对象和结构层,并在该层操作,也可能只考虑对象、结构和属性这三个层次。因而事实上可在任何抽象层次上进行操作。
其次可以对读者进行引导。面向对象分析增加了一个主题层,它可以从一个相当高的层次来表示总体模型。该主题曾能知道读者观察模型,总结问题域的主题。
如何定义主题
1) 如何选择主题
为了选择主题,应该:
为每个结构相应地增加一个主题。
为每个对象相应地增加一个主题。
如果主题的数目超过7,则进一步精炼主题。在识别属性和方法的阶段,一旦确定了对象和结构之间的连接关系,就可以将紧密耦合的主题结合起来以便得到更好的主题层。
在下图中,为了选择主题,可以从类—&—对象和结构层次开始。该图中,可以总结出四个对象:Organization(组织),LegalEvent(法律事件),Person(人)和Vehicle(车辆)。
2) 如何精炼主题
为了精炼主题,可从问题域和接口两方面入手。
使用问题子领域来精炼主题:就是按领域而不是按功能分解的方式来确定主题。
通过使对象间的依赖性最小和交互最少的原则来确定主题:对象间依赖性是由结构和实例连接来表示,而交互则是由消息连接来表示的。可使用结构、属性和方法层去帮助评价所选择主题的影响。
根据问题域的具体情况和最小依赖性原理,可将上面例子中的四个主题精练成两个。
3) 如何构造主题为了构造主题:
,在主题层上标出主题以及主题间的消息连接。
,为主题编号。为了方便通信,每层都要形成一个按主题来分组的图。
,将主题画成一个小方框并取一个适当的名字。连接在案主题层上显示,它反映了该主题和其它主题之间的关系。
面向对象分析通过控制可见性和指导读者的注意力这两条措施实现了7±2原则。其结果是5个层次,即主题、对象、结构方法和属性。
4) 何时引入主题
何时引入主题取决于模型本身的复杂性。对一个很小的系统来说,也许根本不需要主题层;对有较多的对象的系统,应该首先识别对象和结构,然后再识别主题;对很大的项目需要首先识别主题。在这种情况下首先应让高级分析初略地识别对象和结构,然后识别出初始的主题。之后再对主题进行修改和精练。
四、定义属性
1、什么是属性
在面向对象分析中,“属性”被定义用来反映问题域和系统的任务。一个属性就是一些数据(状态信息),它在类的每个对象中均有自己的值。每个类—&—对象都由属性描述,而属性则由类—&—对象规范来描述。
为什么要定义属性
主要原因是属性能为“类-&-对象”以及“结构”提供更多的细节。
选择属性的过程包括分析和选择两步。例如在选择Sensor 的属性时,首先要分析所要强调的是Sensor的外观还是功能。
属性的值(状态)将由该对象的方法来处理。我们把属性和对这些属性进行操作的方法看成一个不可分割的整体,即访问和处理某个对象中的值,它必须指定一个消息连接到该对象所定义的一个方法上去。
注意:随着时间的推移,问题域的“类”保持稳定,但属性却可能改变。
如何定义属性
属性的表示如下图。
用下列步骤来定义属性:
1) 识别属性
首先要明白某个类的对象应该描述什么东西?从单个对象的角度来看,需要询问以下问题:
①一般情况下怎样描述该对象?
②在本问题域中怎样描述该对象?
③在本系统的主要上下文中怎样描述该对象?
紧接着询问以下问题:
④该对象需要了解什么?
⑤该对象需要记住什么状态信息?
⑥该对象能处于什么状态?
同时回忆从前对相同和类似问题域实行面向对象分析的结果。看哪些属性可以重新使用?在定义属性方面可吸取哪些教训?
例如对于一个系统“主管”类—&—对象,应该给它指定相应的属性,即系统需要知道具体哪些的情况?如name,address etc。
在原子概念的层次上标识属性,使每个属性只代表一个“原子概念”,它可以是一个数字,也可以是数字和字母的一个自然数据组。表示“原子概念”的动机是为了产生一个供人观察的简单模型,该模型可能只有几个属性名和自然数据组。
2)定位属性
将每个属性放到它最合适的类-&-对象中。在大多数情况下,这是直接的。例如车辆有属性“出厂日期”和“车体型式”。但当不清楚哪个类—&—对象应该有特定的属性时,需要考查一下问题域本身的一些细节。
对于泛化—特化结构中的类,如果将某个属性放到结构的最上端的类,则该属性适合它所有的特化类。如果每个属性适合于某层的所有特化类,则应将它向上移动到响应的泛化类。如果你发现某个属性有时有值,而有时又没有值,则应研究该泛化—特化结构,看是否存在着另外一个泛化—特化结构。
3) 识别实例连接属性可以描述对象状态,而实例连接则加强了这种描述能力。
①实例连接
一个实例连接就是一个问题域映射模型,该模型反映了某个对象对其它对象的需求。实例连接的表示如下图所示。
0,m
1
实例连接的表示
对象的每条实例连接上均标有量(m)或者范围(m,n),它反映了该对象对其它对象的约束。该量或范围表明可能发生的映射数目或范围。固定数目的连接可以用单个量来表示。例如,一个特定的飞行计划只能是专为一架飞机而制定的,而任何一架特定的飞机可以有零到许多个实例连接到飞行计划。
②策略。
重用以前的结果
为每个对象增加连接线到其它对象。
增加对象间的主题映射,并注意泛化—特化结构上的连接。
为每个对象定义从它出发的连接的量或范围,其中,下限:如果可选则为0,如果是强制性的,则为1或更大;上限:如果为单值则为1,如果为多值则比1大。
在上限比1大的情况下,查看是否某些对象有特殊含义,如最新增加的一个对象,或者已经得到正式批准的对象;如果是,则给该对象相应的类--&--对象符号增加一个属性(如日期,批准状态)。
如果约束是用在某个对象的多个实例连接上的,则它们可在类--&--对象规范模板的“附加约束”节中加以描述。
注意:以相同的方式约束了整体——部分结构。在整体——部分结构和实例连接之间的差别就在于它们的语义强调的不同。前者是人类思维的基本方法之一,而后者仅仅是问题域中对象间的映射,即前者的语义要比后者强得多。
4)、检查特例
当增加属性和实例连接时,需要考虑以下特殊情况。
(1)属性特例
①检查具有不合适值的属性。
如果某个属性有时有合适的值,而有时又没有,则应该用泛化—特化结构策略再次查看是否还存在另一个泛化—特化结构。例如在对象“车辆”中属性“动力”也许有以下值,如内燃,蒸汽或电力。但也有该属性完全不适合的时候,如一台人力拖车。
②检查单属性的类-&-对象。
当遇到只有一个属性的类-&-对象时会有如下两种可能:
a、它是问题域中某事物的一个抽象,本身只有一个属性。这种情况正好。
b、它是另一个类-&-对象的一个属性,不适合于该模型。
单个属性的类—&—对象的一个例子就是类—&—对象“工作人员”,它唯一的属性就是“合法的姓名”。如果这足以反映了系统对“工作人员”的要求,则一切正常。否则需将该属性放到它真正描述的类—&—对象中去,即可简化该模型本身。
③检查每个重复值属性。
确定潜在的重复属性值。如果某个属性有重复值,利用“确定类-&-对象策略”可以找到一个额外的类对象。
(2)实例连接的特例。
①检查每个多对多实例连接。
一个多对多实例连接在每个都有大于1的上限。对这样一个连接,什么样的属性能描述它?
例如考虑在车辆和所有者之间的连接。属性“日期”和“量”描述了某一时刻Vehicle(车辆)与Owner(所有者)之间的交互,在这时就应该在该模型中增加一个“购买”类—&—对象。要注意的是最终结果是是否需要定义额外的类-&-对象。
②检查同类对象之间的实例连接。
对于同一个类的对象之间产生的实例连接,如何描述其映射关系呢?
如果某个映射关系意义比较简单,则只要用该实例连接加上它在类-&-对象规范的“附加约束”节中的描述就足够了。然而即使是这样,也应该查看一下是否需要增加一个新的类-&-对象,以便得到该映射的更多细节。
③检查对象间的多重实例连接。
多重映射隐含着某些语义特征,这些特征可用另一个类-&-对象来描述。
如下图所示,假设某个“LegalEvent”对象知道它到每个“Clerk”对象的连接(读和修改),对于某个不仅负责映射,而且也负责区分“读”和“修改”操作的系统,还需要一个“AccessEvent”类—&—对象,以便能描述在“LegalEvent”和“Clerk”之间不同映射的附加语义。
④检查所需的附加实例连接。
考虑每对对象,并询问以下问题:
a、该映射是否在问题域中?是否在系统的任务范围内?
b、是否该映射在越过其他实例连接时仍然是合适的?如果是合适的,则不需要增加一个实例连接,如果是不合适的,则要增加所需要的连接。
在下图中,一个LegalEvent对象也许有一个连接到Owner和Vehicle。如果Vehicle和Owner能够没有相应的法律事件存在,则该系统应负责该映射,即增加一个实例连接。
该例同样能应用类似的概念到整体——部分结构(它同样也是一个映射,只是语义内容要强得多)。如一个学校既有到学生的连接,也有到俱乐部连接。哪个学生参加了哪个俱乐部,需要一个附加的直接映射。
⑤检查有着特殊意义的连接对象。
当某个连接具有特殊含义时(最近的一个,正式批准的那个),则给受影响的类-&-对象符号增加一个属性(如时间,批准状态)。如下图所示。
5)指定属性
为每个属性取一个标准词汇的、可读性好的名字。然后给每个属性加上简短的描述。
在权衡利弊后,考虑为每个属性增加约束。如果某个约束能简化或减少工作量,则值得增加。同分析有关的其他约束有(对Sensor):测量的单位,范围,限制和计数;精度;缺省值;要求。
下面是一个指定属性的例子:
规范:传感器
属性 型号:制造厂家与型号
初始序列:初始化序列
转换:由比例因子、偏差、测量单位组成
间隔:采样间隔
地址:机内地址
门限:报警门限
状态:操作状态(开,关,监视,等待)
值:最近读到的和转换的值
五、定义方法
1、什么是方法在面向对象分析中,方法是指某个对象所具有的特定行为。一个方法就是收到一条消息后所执行的处理。
定义方法的中心问题是定义所要求的行为。一般有三种常用的行为分类方法:
(1)、有直接动因的行为; (状态—事件—响应)
(2)、进化史上的相似行为; (对象生命历程)
(3)、功能相似的行为。 (最基本的方法)
这些原则被应用到本章所提出的策略之中,特别要提出的是:
a、“对象状态”是建立在“进化”原则基础上的。
b、“所要求的方法”是建立在“功能类似性”和“直接原因”原则基础之上的。
定义方法时的第二个问题是定义对象间的必要属性。如交互模式等。
方法和消息连接是在类—&—对象规范中指定的,因此是满足可观察、可测量的处理要求的。下面将提出识别方法和消息连接的策略
2、为什么要定义方法
方法进一步细化了现实的抽象表示,它表明某个类的对象能提供何种行为。
每个数据处理系统都必须有“数据”和“处理”两部分,方法对应于“处理”。
3、如何定义方法分析人员既可以先从属性入手也可以先从方法入手。在后面的分析中倾向于采用前后向混合的方式来工作。但在本节还按从属性到方法的方式来组织。
方法是放在类—&—对象和类符号的底部,如下图所示。
定义方法包括以下几个步骤:
1)识别对象状态
从创建之时起到释放之时止,每个对象要经历不同的状态。一个对象的状态是由其属性的值来决定和表示的。属性值的每一次改变将反映对象状态的一次变化。
一个对象状态是属性值的标识符,它反映了对象行为的改变。为了识别对象状态,需要检查属性的潜在值,然后再确定这些潜在值的不同行为是否属于系统的任务范围之内。同时查看一下是否能重用相同和类似问题域中从前面向对象分析结果。
例如,考虑前面传感器的属性,其中哪些属性值能反映对象行为中所需的变化呢?究竟哪些值隐含了性能的变化呢?这完全依赖系统的任务。在本系统中,只有名为“状态”的属性能反映行为中的变化。
对象状态图代表一个对象在不同时期的不同的状态或模式,该图能识别状态以及状态转换,如下图中左图所示。下图中的右图是一个传感器的对象状态表示的实例。
注意这里只显示了状态和合法的转换,而实际状态转换和状态行为是在方法规范中指定的。
2)识别所要求的方法本节说明如何识别所要求的两种方法:简单算法方法和复杂算法方法。
(1)简单算法方法简单算法方法可用于模型中的每一个类-&-对象。它们遵循同一个基本模式。
例如:建立一个传感器。
,检查型号的值。
,检查初始化序列的值。
,检查转换的值。
,检查区间的值。
,检查地址的值。
,检查门限的值。
,如果以上一切均正常,则建立和初始化一个新的对象。
,返回结果。
如果定义了属性,则无论它采用何种约束,则可一次性地指定描述如何建立/初始化一个对象的方法。例如:
建立(一个对象)
,检查与约束不符的值。
,如果以上一切均正常,则建立和初始化一个新的对象。
,返回结果。
这种方法可以指定并处理为隐含方法,而且描述隐含方法之间交互的消息连接也被隐含在方法层。当在其他类—&—对象规范中提到时,均以全小写字母出现。
这四种简单算法方法就是创建(Create),连接(Connect),访问(Access)和释放(Release) 。
创建:该方法建立和初始化该类的一个对象。
连接:该方法将一个对象与另一个对象连接起来。
访问:该方法取出或设置一个对象的属性值。
释放:该方法释放(解除连接和删除)一个对象。
系统所要求的大多数性能均可由以上4种隐含方法提供。
(2)复杂算法方法
复杂算法方法主要分为两类:
a、计算(Calculate)—— 该方法根据一个对象的属性值计算一个结果。
b、监视(Monitor)—— 该方法监视一个外部系统或装置。它处理外部系统的输入和输出,负责装置的数据获取和控制。它也许还需要其他方法,如Initialize or Terminate。
在确定一个对象除隐含方法以外还需要什么样的方法时,使用这些方法。
考察对象的状态并询问以下问题:对象在其值上所实行的是何种计算?对象为了检测和响应外部系统或装置的变化所实行的是何种监视?
同样需检查相同或类似问题域中从前面向对象分析结果,看哪个复杂算法的方法能否直接重用。
使用领域有关的方法名字。如对于法律事件的费用计算,可以使用Calculate_Fee,而不要简单地使用Calculate。
3)识别消息连接
(1)什么是消息连接
在面向对象分析中,消息连接是指一个对象到另一个对象的映射(偶尔到一个类)。其中“发送者”向“接受者”发送一个消息,以使得某些处理功能得以实现。所需的处理是在发送者的方法规范中命名,并在接受者的方法规范中定义的。
消息连接完全是为了方法而存在的。在指定方法之前,跟踪消息连接有助于确定该对象同系统其它部分的处理相关性,然后才去考虑该对象本身的行为。消息连接的第一次传递要涉及许多关键的处理相关性。在实际指定方法的过程中,可望得到某些附加的消息连接。
(2)为什么要识别消息连接
处理复杂问题的一条原则就是用消息通信。
从效果看,消息连接组合了事件响应和数据流两种观点,这就是说每个消息连接代表着一个上下文所发送的值和作为结果而接收到的响应。
(3)消息连接的表示法消息连接可以用一个带有箭头的细实线来表示,如下图所示。
在发送者的类—&—对象规范中定义要求发送的消息;在接收者的类—&—对象的规范中定义要实行的方法。
对于从一个对象向许多对象辐射出来的消息连接,可使用上图中右图的表示法。该表示法只有在所有消息连接的图形显示有利于理解模型时才能使用。
命令是人与系统交互的十分自然的方式。在面向对象分析的部分模型中采用了与此十分类似的交互方式,如下图中左图所示。人被认为是在与整个模型交互,调用所想要的方法(推荐这种方式)。
另一种方式就是在模型本身中引入人的交互的消息连接,如上图中右图所示。图中为多头消息连接的符号。
(4)识别消息连接的策略
为了识别所需的消息连接,必须对每个对象询问以下问题:
①它需要哪些其它对象提供方法?画一个箭头到这些对象中的每一个;
②哪些其它对象需要它的方法?从这些对象中的每一个画一个箭头到所考虑的对象;
③沿着消息连接到下一个对象,并重复这些问题。
同样需查看以前结果,看是否可直接重新使用。
线程(thread)是进程内部的一个可执行的路径。
从一个消息到另一个消息,再到一个消息。这种执行线程有助于分析人员检查模型的完整性和确定实时处理需求。这些执行线程可加上分析约束(特别是对实时系统而言)。线程本身是用消息连接和规范正文来描述的。
下图描述了实时空运系统中的关键执行线程。
注意:线程总开销是由参加的方法和消息连接来分担的。
4)指定方法在一个类—&—对象模块中(如下图所示),可使用方法图来指定方法。
specification (对象名)
attribute (由occur操纵的属性)
attribute (可适用于多个对象或分类结构实例的属性)
attribute (只是偶尔可导出的属性)
externalInput (来自设备或外界系统的输入)
externalOutput (向设备或外界系统的输出)
objectStateDiagram (对象状态图)
additionalConstraints (附加约束)
note (分析折衷考虑)
method <name & Method Chart> (方法名和方法框架图)
method <name & method chart>
method <name & method chart>
traceabilityCodes (用来回溯到以前的需求文档的代码)
applicableStateCodes (合适的状态代码)
timeRequirements (时间要求)
memoryRequirements (记忆要求)
图 类—&—对象模板在该模板中,方法图以图形方式描述方法要求,如下图所示。
注意:方法图以预条件、触发和终止条件来表达与状态有关的行为。
1、一个例子——“创建”
下面一个例子是隐含方法“创建”的方法图,如下图所示。
2、正文块格式在每个正文块中采用统一的格式,即要么使用词组要么使用完整的句子。
指定每个对象的外部可观测行为。每次都有询问一下:“这个需求是否可以从外部观测?”,并考虑为每个需求书写一段测试程序。
5)准备完整的面向对象分析文本集完整的文本集应包括以下内容:
.5层面向对象分析模型。
主题、类—&—对象、结构、属性和方法
.类—&—对象规范。
.在需要时补充文本。
关键执行线程表
附加的系统约束
方法/状态表在日程和经费预算的限制条件下,决定何时完成分析与规范完全取决于领域状况、系统的任务以及质量检查表(包括策略检查和模型一致性检查)。
面向对象分析(object-oriented analysis,OOA)是面向对象软件工程方法的第一个环节,包括一套概念原则、过程步骤、表示方法、提交文档等规范要求。
OOA的任务是采用面向对象方法,把对问题论域和系统的认识理解,正确地抽象为规范的对象(包括类、继承层次)和消息传递联系,形成面向对象模型,为后续的面向对象设计(object-oriented design,OOD)和面向对象编程(OOP)提供指导。而且,OOA与OOD能够自然地过渡和结合,也是面向对象方法值得称道的一个优点。
1.3.1 OOA方法评价促使人们从面向过程程序设计往面向对象程序设计方法转换的原因是因为面向对象方法更适合于解决当今的庞大、复杂和易变的系统模型。自20世纪80年代后期以来,相继出现了许多OOA和OOD方法,如:Booch方法(OOD)、Cood-Yourdon方法(OOAD)等等。
OOA的各种方法尽管在概念和模型上不尽相同,但都是为建立系统的面向对象模型目标而进行的探索。评价分析方法主要是看它是否具有OOA的如下优点:
(1)是在人类思维组织的基本方法框架下定义并表达需求,直观性好(共同语言)。
(2)集中精力于问题空间的理解和分析,有利于超越系统的复杂性困难。所建立的系统模型清晰,问题模型与程序中的类相对应,系统扩充和改良较为方便。
(3)把属性和有关服务方法作为对象整体来看待,比较自然。特别重要的是,对象在问题论域中比较稳定,当需求变化时,可能需要增加新的对象,但原有的基本对象还可保留使用。
(4)使用对象间的最小相关性来分析和说明。这有利于实行封装性原则,并使OOA适应开发需求的变化,也有利于制作和提取可复用的部件。
(5)通过对共性的显式表示而提高表达能力。抽象层次与后续OOP结合,编程思路清晰,特别有利于提高程序效率。
(6)分析法与设计法的一致性,密切配合建造一个问题域模型。
(7)对系统族的适用性和可扩展性强。
1.3.2 OOA步骤面向对象分析的关键是对问题域中事物的识别和它们之间的相互关系的判定。根据设计进程和分析问题的繁简程度,把系统或问题分解成为一些对象,并以消息的形式在各对象间建立联系。
基于面向对象的方法学原则进行系统分析时,一般要进行如下步骤:
(1)分析确定并标识构成系统的各个组成部分(即对象),并进行抽象分类。划分主题及类是从大的单元来理解系统的方法,主题是一组类与对象,主题的大小应合适地选择。
(2)分析确定每一组成部分(即对象)的结构,具体的分析原则:第一是按照一般——特殊结构,确定标识类间的继承关系;第二是按照整体——部分结构,确定一个对象怎样由其他对象组成,或者是如何将一些对象组合成大对象。
(3)认识并建立每一对象及其相互之间的关系。以应用为基础标识对象,定义对象的内部特征(属性、方法),建立消息连接和实例连接。
(4)分析对象的动态行为,规划并建立各组成部分(即对象)间的通信关系和接口协议形式。
(5)进一步协调和优化各个组成部分的性能及相互关系,精炼候选的类/对象,使系统成为由不同部分(即对象)组成的最小集合。
(6)分析、设计每个组成部分(即对象)的功能实现细节,检查分析模型的一致性和完整性。
在OOA中,同样要强调软件工程的事务分离原则(principle of separation of concerns),即将基本需求与实现区别开来。建立分析模型时,主要精力应集中于捕捉那些本质的或逻辑的系统需求,确定系统的基本行为。
1.3.3 OOA模型
OOA过程是一个建立系统基本行为的过程,需要采用构造待开发系统的形式模型。关于建模的机制,本书采用Peter Coad 和Ed Yourdon 在1991 年提出的一种循序渐进的面向对象分析方法。
OOA模型采用分层次结构,划分为5层次,它们分别是:
1,对象-类层
表达待开发系统及其环境信息的基本构造单位,标出反映问题域的对象和类,并用符号进行规范的描述,以信息提供者熟悉的术语为对象和类命名。
2,属性层
定义对象和某些结构中的数据单元,继承结构中所有类的公共属性可放于通用类中。标识对象必须的属性并放在合适的继承层次上,实例连接关系和属性的特殊限制也应标识出来。
3,服务层
表示对象的服务或行为,即要定义类上的操作。列出对象需要做什么(即方法),给出对象间的消息连接(并应以箭头指示消息从发送者到接受者),消息系列用执行线程来表达,服务用类似流程图的方式表达。
4,结构层
识别现实世界中对象之间的关系,当一个对象是另一个对象的一部分时,用“整体-部分”关系表示;当一个类是类属于另一个类时,用类之间继承关系表示。
5,主题层
用于管理在系统的一个方法,这里所说的“主题”可以看成是子模型或子系统,可将相关类或对象分别归类到各个主题中,并赋予标号和名称。
总之,OOA模型的基本要求是明确系统中应设立哪些对象/类,每一类对象的内部构成,各类对象与外部的关系,形成一个完整的模型图。在此基础上,还应按需要提供主题图,以帮助使用者能够在不同粒度层次上理解系统。
1.3.4 OOA视图
P12图1.3显示了三种在世界上较为流行的面向对象标记,其中又以Coad/yourdon最为简明,被更多的人所接受,本书也采用该图示法。图1.4显示了OOA模型的符号表示及其说明。
1.3.5 OOA提交在正式完成OOA活动时,对系统提供模型化描述,具体地描绘其静态结构(对象模型)和动态功能,包括使用数据流图、实体-关系图、状态-迁移图(参考第七章)。同时应当提交完整的OOA文档,包括下列主要成果:
(1)书写用于指导设计和实现的分析方案说明;
(2)精选的候选类清单;
(3)提交数据字典;
(4)使用OOA模型符号图示,绘制类图、主题图等;
(类间继承关系);
(对象间整体-部分关系、一般-特殊关系);
(5)类定义模板(类的整体说明、属性说明、方法和消息说明);
(描述可按OOA工具和CASE环境要求,可填写对话框中的表格);
(6)指定优化规则。