第9章面向对象的系统分析徐天宇9.2系统分析面向对象系统分析阶段的主要任务是分析问题域(即应用领域)和系统责任,找出问题解决方案,发现对象,分析对象的内部构成和外部关系,产生一个符合用户需求,并能够直接反应问题域和系统责任的对象模型及其详细说明。系统分析具体来说,分析阶段的活动主要是:识别对象;确定类;确定类的属性和操作;确定类之间的关系:确定对象之间的交互:确定对象的状态变化等。9.2.1识别对象识别对象并不是从零开始的工作,应该最大限度地利用已有的劳动成果。比较典型的可利用的资料有。用例图和用例描述。术语表。权威的术语定义集合。课程注册系统的术语表课程课程目录职员财务系统年级教授学期成绩单名册学生教学日历三个要点识别对象的三个要点。从上述来源中找出候选的对象集合,根据对象的基本含义作出相应取舍。将被确认的对象以类的形式加入设计模型,为每个对象作简要文字说明。将对象绘制在一张(或者多张)描述类之间关系的类图中,标识现阶段能够确认的关系。1.发现对象用例图和用例描述是用来发现对象的重要资料,为了寻找对象需要认真阅读它们,阅读时先将名词划出来。但名词可能是参与者、对象和对象属性,所以还要区别它们。发现对象参与者通常比较容易区别,区别对象和对象属性可以通过分析是否有行为,对象是有行为的,而属性只是单纯的信息。对象是有属性的。并不是所有的对象都能通过用例图和用例描述发现,三种对象类型分析模型中最常用的三种对象类型,它们是:实体(Entity)边界(Bountary)控制(Control)⑴实体对象实体对象主要的任务是保存信息,同时也具有相关的行为,但是这部分行为主要包括那些和实体对象自身信息直接相关的操作。可以找到实体对象的几个办法①考虑解决问题所需要的全部数据和行为,然后将数据按相关性分组。②识别出重要的名词,并将它们作为实体对象,然后确定每一个实体对象包含的数据和行为。识别实体对象可参考的问题:该对象是否是某个问题中的重要的名词?该对象是否包含用来解决系统问题的重要的信息?该对象是否与用来解决系统问题的重要的动作有关?⑵边界对象边界对象用于描述拟建系统内部运作与外部环境之间的交互,主要负责内容的翻译和形式的转换,并表达相应的结果。边界对象主要用于描述三种类型的内容:拟建系统和用户的界面,拟建系统和外部系统的接口拟建系统与设备的接口。⑵边界对象通过检查在用例图中的参与者与用例之间的关系,我们可以识别出边界对象。通常,在分析模型中,每一对参与者/用例都构成了一个边界对象。识别边界对象用户外部系统用户界面外部系统接口用例识别边界对象的可参考的问题该对象是否描述了必须显示的信息以及必须提供的服务?该对象是否包含所有的接口设计细节?该对象是否描述了与外部系统的交互?⑶控制对象控制对象用于描述对一个用例所特有的事件流的控制行为。控制对象相当于协调人它知道那些类有能力完成具体的任务。通常一个用例对应一个控制类。识别控制对象可参考的问题是否对业务逻辑进行控制?是否将业务逻辑结果提交给实体对象?顺序图中的边界对象,控制对象和实体对象:实体对象:用户:边界对象:控制对象输入信息请求处理处理建立连接数据处理2.描述对象的行为在已确定的三类对象的基础上,运用顺序图和协作图可以反映三类对象的协作关系。以上得到的信息只展示了对象和对象之间的静态关系,并不完整。我们还需要详细了解对象在系统中的行为和责任。责任责任是消息响应者应做的事。消息被要求者提出,责任由响应者承担。确定责任主要根据责任和消息的简明对应关系,所谓找出责任是根据消息的要求定义责任,即用责任满足消息所提出的要求。⑴对象的行为对象的行为是通过系统中对象之间的交互以及对象内部状态的转化来表现的。对象间通过发送消息而产生交互。同时在一个对象的生命周期内也存在状态的转移以及对事件的响应。动态分析的主要任务动态分析的主要任务包括分析用例的实现过程(要求有详细的用例描述),从而更好地理解业务流程以及为发现类打好基础;动态分析的UML图用于进行动态分析的UML图包括顺序图、协作图、活动图和状态图。这几种图从不同的角度和方面和描述对象的动态行为。⑴系统动态分析交互图表现的是参与者与系统以及系统内部对象之间的交互,创建交互图时要记住,你是在向对象指定职责。将消息加进交互图时,是在向接收消息的对象指定职责。顺序图与事件流用例的事件流中可能包含多个事件流,通常有一个基本事件流和多个分支事件流、替代事件流。每个事件流应用一个顺序图描述。场景和用例用例中的场景描述可以是形成系统对象图的一个出发点。它对于系统中对象的发现有极大的帮助。用例一般是由多个场景组合而成的,每个场景代表了用例的一个实例。⑵对象状态分析状态图针对单个对象建模,通过分析单个对象的内部状态转换来了解一个对象的行为。对于有多种内部状态的对象,状态图可以显示对象如何从一种状态过渡到另外一种状态,以及对象在不同状态中的不同行为。通过分析某一对象的状态变化,为设计此对象的操作提供依据。步骤分析一个对象的状态可采用下列:①首先要确定该对象有那些状态是问题域所关心的。。②分析对象生命周期,确定对象活动“历程”;③获取一系列候选状态;④针对每一个候选状态,分析出对象在此状态下的动作。确定对象状态的两种方法:检查类的属性:考虑一个类的实例在属性值不同时如何表现,因为如果对象的行为表现不同,则其状态也不同。例:某培训班的人数属性50人10人检查类的关联检查类的关联:看看关联多重性中带0的关联,0表示这个关联是可选的。关联存在和不存在时类的实例是否表现相同?如果不同,则可能有多种状态状态与属性打开关闭透支do/通知客户取钱[结余小于0]存款[结余小于0]客户请求关闭检查结余[结余小于0达30天以上]9.2.2创建分析类图创建分析类图的工作主要包括:确定分析类和确定分析类的操作、属性和类之间的关系分析类的概念分析模型中的所有类都是”分析类”。从设计视角看待,“分析类”忽略实现细节,相当粗略。“分析类”是为定义设计类做准备的。一个”分析类”可以创建一个设计类,也可以创建多个。1.确定“分析类”创建分析类图首先确定一组备选的、能够执行用例中行为的“分析类”。“分析类”的实例应该满足用例的所有的需求。三种“分析类”边界类:每个参与者和用例的交互存在一个对应的边界类。一个用例可能有多个边界类。它很可能是用户的使用界面,如结账用例的结账页面。控制类:一般一个用例对应一个控制类。它一般存在于特定的应用层,它可能处理了业务逻辑。实体类:这个主要看用例里面用到的持久的数据对象。控制类要用到数据库对象时,可能就使用了实体类。获取边界类分析参与者与用例对,找出边界类边界类的复用控制类的考虑如果不同用例包含的任务之间有比较紧密的联系,某些控制类可以参与多个用例实现。当用例事件流非常简单的情况下,控制类的必要性明显降低。实体类的考虑实体类的适用范围和生命周期可能超越特定的用例事件流。实体类通常不是某一特定用例所专有的。2.分析类的获取类的获取有两种办法:一种是从用例的用例描述开始,检查事件流中的每个名词。描述用例的事件流中有4种名词:参与者、类、类的属性、其他描述性名词。能够找出实体类⑴根据事件流中的名词找出实体类去掉不必要的类和不正确的类根据下列标准,去掉“银行网络系统”不必要的类和不正确的类。(1)冗余类:若两个类表述了同一个信息,保留最富有描述能力的类。如用户和顾客就是重复的描述,因为顾客最富有描述性,因此保留它。(2)不相干的类:除掉与问题没有关系或根本无关的类。例如,摊派费用超出了银行网络的范围。(3)模糊类:类必须是确定的,有些暂定类边界定义模糊或范围太广,如记录保管就模糊类,它是事务中的一部分。(4)属性:某些名词描述的是其他对象的属性,则从暂定类中删除。如果某一性质的独立性很重要,就应该把他归属到类,而不把它作为属性。(5)操作:去掉不必要的类和不正确的类在银行网络系统中,模糊类是系统、安全措施、记录保管、银行网络等。属于属性的有:帐户数据、收据、现金、事务数据。属于实现的如:访问、软件等。这些均应除去。⑵根据交互图发现分析类检查交互图中的对象,研究对象具有的共同属性和操作来发现类。如果采用第二种方法创建类图,需要先创建交互图。3.合并分析类分析了所有用例以后,并为每一个用例创建了类图,就要合并各种不同的分析类来达成一个系统的分析模型。这一个阶段的任务是对不同用例中相同类型的分析类进行分析,看它们是否相同,如相同则考虑合并。合并后的分析类图4.识别分析类操作通常有两种方法为类识别操作:第一是责任驱动法,第二是通过交互图⑴责任驱动法识别类“操作”责任驱动主要基于两个概念:第一,一个对象在系统中负有一定的责任,例如它要获得特定的信息(了解的责任)和为其他对象提供特定的信息(做的责任);第二,一个对象与其他对象合作来提供所要求的服务。责任驱动法识别类“操作”类的责任可以从用例描述导出,可以首先定义用例所包含的系统责任,然后,在系统的类中识别这些责任。CRC卡技术责任分析的一种有用技术CRC(Class-Responsibility-Collaboration)卡技术。也就是为每个类创建一个CRC卡,其中包括类名、类责任和完成每个责任所需的协作者的描述。还可以将类的详细描述写在卡的背面。这种方式充分体现了“用例驱动”的思想。为类分配操作——CRC卡类的名称类的名称责任1责任1的协作者对该类的描述…责任2责任2的协作者责任3责任3的协作者……注册讨论班的CRC卡⑵用交互图描述用例来为类识别“操作”面向对象系统是通过对象间相互发送消息来完成系统功能的。所以,这些对象间传递的消息就可以映射为对象的操作。有助于寻找类操作的问题(1)有哪些类会与该类交互,包括该类本身?(2)该类接收哪些类(包括自己)发送的消息,收到消息之后进行什么处理?(3)该类向哪些类发送消息,消息的内容是什么,在发送之前该类需要做什么处理?(4)该类中需要哪些操作来维持自身属性的一致性、完整性,以及自身属性的更新?⑶分析类操作的设计简要标识分析类的“操作”。同样要给“操作”起一个易于理解的名字,通常要比较简短一个类的操作太多或太少都是不合适的5.识别分析类属性“分析类”要能执行相应的操作,它要依赖于两方面的内容:一方面是利用它自己保存的信息;另一方面是利用其他的类。类自己所能够保存的信息就是它的属性①识别出类的属性有些类的属性可以从前面得到的文档中找到。通常,在用例描述中用名词表示属性,如“图书的出版社、价格等”。有助于识别类属性的问题①按一般常识这个类应该具有哪些属性?②在当前的问题域中类应该具有什么属性?③根据系统责任的要求,这个类应该具有哪些属性?④建立这个类是为了保存和管理哪些信息?⑤有哪些需要区别的状态,是否需要增加一个属性来区别这些状态?②获得属性的渠道属性的来源有许多。获得属性的渠道有几个:⑴通过查看用例文档,寻找事件流中的名词。⑵通过查看文档,发现系统要收集的信息,这些信息就是类的属性。⑶如果已经定义了数据库结构,则数据库表中的字段就是属性。③确定分析类属性的基本原则要确认它相对于相应对象或类的每一个实例都是适用的。属性应当是一种相对的原子概念,类的属性不宜太多,如果某个类的属性太多,最好将其分解成更小的类。④属性的类型属性的类型指属性值的类型。可以是基本数据类型,例如整数、实数、布尔型、字符串型等,也可以是用户自定义的类型。分析阶段一般不需要确定属性的类型6.描述分析类之间的关系类之间的关系有关联关系、聚合关系、组合关系、泛化关系、依赖关系。1)类之间的关系建模通常按照以下步骤对类之间的关系建模:找出关系→绘制分析类图→给关系命名→设置多重性→设置其他特性有的类只和其他一个类有关系,而