[c++读书笔记]面向对象的分析 |
面向对象分析的过程 面向对象的分析着重分析问题域和系统责任,确定问题的解决方案,暂时忽略与系统实现有关的问题,建立独立于实现的系统分析模型。面向对象分析的基本过程如下:(1) 问题域分析 分析应用领域的业务范围、业务规则和业务处理过程,确定系统的责任、范围和边界,确定系统的需求。在分析中,需要着重对系统与外部的用户和其他系统的交互进行分析,确定交互的内容、步骤和顺序。(2) 发现和定义对象与类 识别对象和类,确定它们的内部特征,即属性和操作。这是一个从现实世界到概念模型的抽象过程,是认识从特殊到一般的提升过程。 抽象是面向对象分析的基本原则,系统分析员不必了解问题域中繁杂的事物和现象的所有方面,只需研究与系统目标有关的事物及其本质特性,并且舍弃个体事物的细节差异,抽取其共同的特征而获得有关事物的概念,从而发现对象和类。(3) 识别对象的外部联系 在发现和定义对象与类的过程中,需要同时识别对象与类、类与类之间的各种外部联系,即结构性的静态联系和行为性的动态联系,包括一般与特殊、整体与部分、实例连接、消息连接等联系。 对象和类是现实世界中事物的抽象,它们之间的联系要从分析现实世界事物的各种真实联系中获得。(4) 建立系统的静态结构模型 分析系统的行为,建立系统的静态结构模型,并将其用图形和文字说明表示出来,如绘制类图、对象图、系统与子系统结构图等,编制相应的说明文档。(5) 建立系统的动态结构模型 分析系统的行为,建立系统的动态行为模型,并将其用图形和文字说明表示出来,如绘制用例图、交互图、活动图、状态图等,编制相应的说明文档。 现实世界中事物的行为是极其复杂的,需要从中抽象出对建立系统模型有意义的行为。在分析中需要控制系统行为的复杂性,注意确定行为的归属和作用范围,确定事物之间的行为依赖关系,区分主动与被动,认识并发行为和状态对行为的影响。系统的静态结构模型和动态行为模型、必要的需求分析说明书、系统分析说明书等一起构成了系统的分析模型,这是系统分析活动的成果,成为下一步系统设计的基础。
用例模型在系统建模过程中是十分重要的,它影响着其他视图的建立和系统的实现。对不同的人员来说,用例模型具有不同的用处: * 客户使用它,详细说明系统应有的功能,并描述系统的使用方法; * 开发人员使用它,有助于理解系统的需求,为后续阶段的工作(如分析、设计和实现)奠定基础; * 系统集成和测试人员使用它,验证最终实现的系统是否与用例模型说明的功能一致; * 文档人员使用它,为编写用户手册提供参考。建立用例模型的过程如下: (1) 找出系统边界以外的角色(actor),角色是与系统进行交互的外部实体,可以是与系统交互的人员、与系统相连并交换信息的设备和其他系统; (2) 从这些角色如何与系统进行交互的角度,使用用例(use case)来描述角色怎样使用系统以及系统向角色提供什么功能,用例所表示的是从外部用户角度观察的系统功能; (3) 绘制用例图,并编写详细的用例描述。用例图只能宏观地描述系统的功能,但却不能提供用例模型所必需的所有信息,每个功能的含义和具体实现步骤则以文本方式描述。 下面,我们采用一个简单的例子说明用例模型的基本概念和建立过程。 用例模型用于描述系统的基本功能,其中,角色代表外部实体,如用户、硬件或其他外部系统,用例代表一个完整的功能。角色启动用例并与之通讯,执行中的用例是一个动作序列。用例的具体执行过程需要用文本进行描述。
举例:学生注册课程系统 某大学准备开发一个学生课程注册系统,学生可以使用该系统查询新学期将开设的课程和讲课教师情况,选择自己要学习的课程进行登记注册,并可以查询成绩单;教师可以使用该系统查询新学期将开设的课程和选课学生情况,并可以登记成绩单;注册管理员使用该系统进行注册管理,包括维护教师信息、学生信息和课程信息等。 在每个学期的开始,学生可以获得该学期的课程目录表,课程目录表列出每门课程的所有信息,诸如基本信息、教师、开课系和选课条件等。 新学期开始前两周为选课注册时间,在此期间学生可以选课注册,并且允许改变或取消注册申请,开学两周后注册管理员负责关闭课程注册。每个学生可以选择不超过4门课程,同时指定2门侯选课程以备主选课程未选上。每门课程最多不能超过10人,最少不能低于3人,低于3人选课的课程将被取消。一旦学生的注册过程完毕,注册系统将有关信息提交收费系统以便学生付费。如果在实际注册过程中名额已满,系统将通知学生在提交课程表之前予以更改。 在学期结束时,学生可以存取系统查看电子成绩单。由于学生成绩属于敏感信息,系统必须提供必要的安全措施以防非法存取。
发现角色 简单地说,角色是与系统交互的人或事。所谓"与系统交互"意味着向系统发送消息,从系统中接收消息,或是与系统交换信息。有些角色可以初始化用例,有些角色则不然,仅仅参与用例,在某个时刻与用例进行通信。在UML语言中,角色用一个小人的图形和名称来表示。我们可以通过回答下列问题,进行系统角色的识别: * 谁使用系统的功能? * 谁需要借助系统完成日常工作? * 谁来维护和管理系统,以保证系统正常工作? * 系统控制的硬件设备有哪些? * 系统需要与其他哪些系统交互? * 谁对系统产生的结果感兴趣? 在上述例子中,学生和教师使用系统完成课程注册和成绩登记等,注册管理员维护和管理教师、学生和课程的信息。另外,新系统存取已有的课程目录数据库,获得课程列表。因此,我们可以识别出如图4.15所示的角色。
学生注册课程系统的角色
发现用例 用例代表一个完整的功能,如与角色通信、进行计算或在系统内工作等。用例具有以下的特征: * 用例总是由角色初始化; * 用例为角色提供值; * 用例具有完全性,即不管其内部是如何实现的,只有最终产生了返回角色的结果,用例的执行才能完毕。 用例描述了它所代表的功能的各个方面,即包含了用例执行期间可能发生的种种情况。用例和角色之间具有"关联"的连接关系,表示什么角色与该用例进行通信。在UML语言中,用例用一个椭圆图形和名称表示。 实际上,从识别角色开始,发现用例的过程就已经开始了。对于已识别的角色,通过询问下列问题,我们可以发现用例: * 角色需要从系统中获得什么功能?角色需要做什么? * 角色需要读取、产生、删除、修改或存储系统的某些信息吗? * 系统中发生事件需要通知角色吗?角色需要通知系统某件事情吗? * 系统需要的输入/输出信息是什么?这些信息从哪儿来到哪儿去? * 采用什么实现方法满足某些特殊要求? 在上述例子中,我们通过上述提问可以识别以下用例: * 与教师有关的用例 选择课程--选择所教的课程,并获得学生名册; 登记成绩--在学期结束时,提交学生的课程成绩。 * 与学生有关的用例 注册课程--在学期开始进行选课注册,允许在一段时间内更改或删除,课程目录系统提供当前学期的所有可选课程列表; 查看成绩单--学生可以查看以前学期的电子成绩单。 * 与注册管理员有关的用例 维护课程信息--在系统中增加、修改和删除课程信息; 维护学生信息--在系统中增加、修改和删除学生信息; 维护教师信息--在系统中增加、修改和删除教师信息。 关闭注册--删除少于3人的课程,并由付费系统通知学生缴费。 * 与安全性要求有关的用例 登录--使用此系统的人员需要进行登录,以验证其身份和权限。
用例之间的关系
除了与角色关联外,用例之间还可以具有包含和扩展的关系。* 包含(<<include>>) 尽管每个用例是独立的,但也可以分解成更加简单的用例,这种用例之间的关系称为包含。一般情况下,如果若干用例的某些行为都是相同的,则可以将这些相同的行为提取出来单独组成一个用例。当其他用例使用该用例时,便包含了该用例的所有行为。包含关系用带关键字<<include>>的虚线来表示,箭头指向被包含的用例。* 扩展(<<extend>>) 在一个用例中加入一些新的动作,则构成了另一个用例,这种用例之间的关系称为扩展。扩展用例可以根据需要有选择地继承原有用例的部分行为,扩展关系用带关键字<<extend>>的虚线来表示,箭头指向被扩展的用例。
描述用例 前面提到,单纯使用用例图不能提供用例所具有的全部信息,因此,需要使用文字描述那些不能反映在图形上的信息。用例描述实际上是关于角色与系统如何交互的规格说明,要求清晰明确,没有二义性。描述用例时,应该只注重外部能力,不涉及内部细节。用例描述主要包括以下内容:* 目标 简要描述用例的最终任务和结果。* 事件流 (1) 说明用例是怎样启动的,即哪些角色在什么情况下启动执行用例。 (2) 说明角色和用例之间的信息处理过程,如哪些信息是通知对方的,怎样修改和检索信息的,系统使用和修改了哪些实体等。 (3) 说明用例在不同的条件下,可以选择执行的多种方案。 (4) 说明用例在什么情况下才能被视作完成,完成时结果应传给角色。
通常,事件流包括基本流程和可选流程两部分。基本流程说明了角色和系统之间相互交互或对话的顺序,当这种交互结束时,角色便实现了预期目的;可选流程也可促进成功地完成任务,但它们代表了任务的细节或用于完成任务的途径的变化部分。在交互过程中,基本流程可以在一些决策点上分解成可选流程,然后再重新汇成一个基本流程。在图4.16中,Step1~5为基本流程,Step3a~3c为可选流程。* 特殊需求 说明此用例的特殊要求。* 前提条件 说明此用例开始执行的前提条件,如角色登录成功等。* 后置条件 说明此用例执行结束后,结果应传给什么角色。 下面我们给出上述例子中"登记成绩"的用例描述。
用例:登记成绩1. 目标 本用例允许教师提交上学期完成的一门或多门课程的学生成绩。2. 事件流 基本流程 当教师希望提交上学期完成的一门或多门课程的学生成绩时,本用例开始执行。 (1) 系统显示教师上学期所教的课程列表; (2) 教师选择所教课程; (3) 系统检索出已注册此课程的学生列表,显示每个学生及其以前所给的成绩; (4) 对于列表中的每个学生,教师输入百分制成绩,系统记录所提供课程的学生成绩。如果教师希望跳过某个特定的学生,其相应的成绩可以为空,以后在进行填写。教师可以修改学生的成绩。 可选流程 在主流程中,如果教师在上学期没有教课,系统将显示错误信息,教师接受此信息,用例结束。3. 特殊需求 无。4. 前提条件 用例开始之前,教师必须在系统登录成功。5. 后置条件 如果用例执行成功,所提供课程的学生成绩被更新,否则,系统状态不变。
发现和定义对象类应以问题域和系统责任为出发点,正确地运用抽象原则,尽可能全面地发现对象的因素,并对其进行检查和整理,最终得到系统的对象类。我们可以在用例模型的基础上,通过识别实体类、边界类和控制类,从而发现和定义系统中的对象类。 在这里,实体类表示系统存储和管理的永久信息,边界类表示角色与系统之间的交互,控制类表示由系统支持和用户执行的任务,我们使用UML中的构造型<<entity>>、<<boundary>>和<<control>>分别表示实体类、边界类和控制类。
识别实体类 实体类代表系统中需要存储和关系的信息,通常是永久存在的。启发分析员发现实体类的因素包括: * 人员:通常系统会涉及到各种各样的人员,我们需要考虑的是由系统保存和管理其信息的人员,如教师、学生等。 * 组织:在系统中发挥一定作用的组织机构,如系、班级等。 * 物品:需要由系统管理的物品,可以是有形或无形的,如课程等。 * 设备:在系统中动态地运行、由系统进行监控或供系统使用的各种设备、仪表、机器、运输工具等。 * 事件:需要由系统长期记忆的事件,如学生注册课程的记录等。 * 表格:这里的"表格"是广义的,可以是各种业务报表、统计表、申请表、身份证、商品订单、帐目、学生成绩单等,注意不要将原始的表格进行简单对应,应该是分析和整理后形成的映射一些现实事物的表格。 在学生课程注册系统的例子中,通过分析和理解问题域,我们找出以下实体类:
实体类
说 明
Professor
学校中讲课的教师
Student
学校中注册课程的学生
Schedule
学生在新学期选择登记的课程列表
CourseCatalog
学校所有课程的目录
Course
课程的基本信息
CourseOffering
新学期课程的开设信息,如讲课教师、时间、地点等信息
识别边界类 边界类代表系统与角色的接口,在每一个用例中,一个角色对应一个边界类。边界类收集来自角色的信息,并将其转换成实体类和控制类可以使用的中间接口。 根据角色的不同类型,边界类可以是用户接口、系统接口和设备接口。对于用户接口来说,边界类集中描述了用户与系统的交互信息,而不是描述用户接口的显示形式,如按钮、菜单等;对于系统接口和设备接口来说,边界类集中描述所定义的通信或交换协议,而不是说明协议如何实现的。 在学生课程注册系统的例子中,通过发现用例-角色对,我们定义以下边界类:
边界类
说 明
LoginForm
为教师、学生和注册管理员提供登录的操作
RegisterCoursesForm
为学生提供选课注册的操作
ViewReportForm
为学生提供成绩查询的操作
SelectTeachCoursesForm
为教师提供查看学生选课情况的操作
SubmitGradesForm
为教师提供登记成绩的操作
MaintainProfessorsForm
为注册管理员提供维护教师信息的操作
MaintainStudentsForm
为注册管理员提供维护学生信息的操作
MaintainCoursesForm
为注册管理员提供维护课程信息的操作
CloseRegistrationForm
为注册管理员提供关闭注册的操作
BillingSystemNotice
提供与收费系统的信息交换接口
识别控制类 控制类负责协调边界类和实体类,通常在现实世界中没有对应的事物,它负责接收边界类的信息,并将其分发给实体类。 控制类与用例存在着密切的关系,它在用例开始执行时创建,在用例结束时取消。一般来说,一个用例对应一个控制类。当用例比较复杂时,特别是产生分支事件流的情况下,也可以有多个控制类。在有些情况下,用例的行为十分简单,这时可以没有控制类,学生注册课程系统中的用"登录"就是这种情况。 在学生课程注册系统的例子中,我们发现以下控制类:
控制类
说 明
RegisterCoursesControl
负责新学期学生的选课登记
ViewReportControl
负责学生成绩的查询
SelectTeachCoursesControl
负责新学期课程的学生选择情况
SubmitGradesControl
负责学生成绩的登记
CloseRegistrationControl
负责关闭课程注册
将用例行为分配到对象类 识别上述对象类之后,通过建立交互图,我们将用例的行为分布到这些对象类中。 时序图表示完成某项行为的对象类和这些对象类之间传递消息的时间顺序,其组成如图4.17所示。
时序图的组成
其中,对象生命线是一条垂直的虚线,表示对象存在的时间;控制焦点是一个细长的矩形,表示对象执行一个所经历的时间段;消息是对象之间的一条水平箭头线,表示对象之间的通信。 以学生课程注册系统中的用例"注册课程"为例,图表示其中创建课程登记表的时序图。
500)this.width=500'>
用例"注册课程"中创建课程登记表的时序图
协作图包含一组对象和以消息交换为纽带的关联,用于描述系统的行为是如何由系统的成分合作实现的。协作图与时序图是同构的,二者表示的都是同样的系统交互活动,只是各自的侧重点不同而已,下图表示"注册课程"中创建课程登记表的协作图。
500)this.width=500'>
用例"注册课程"中创建课程登记表的协作图
通过对用例建立交互图,我们实现了将系统责任分配到对象类中,即交互图中的每一个消息就是消息接收对象的一个服务。最后,审查和整理对象图,删除一些不必要的冗余操作,分解或合并某些对象类。定义属性对于每个对象,我们从以下方面考虑并发现对象的属性: (1) 按照一般常识,找出对象的某些属性,如人员的姓名、性别、年龄、地址等; (2) 认真研究问题域,找出对象的某些属性,如商品的条形码、学生的学号等; (3) 根据系统责任的要求,找出对象的某些属性; (4) 考虑对象需要系统保存和管理的信息,找出对象的相应属性,如"课程"需要保存和管理的信息; (5) 对象为了在服务中实现其功能,需要增设一些属性; (6) 识别对象需要区别的状态,考虑是否需要增加一个属性来区别这些状态; (7) 确定属性表示整体与部分结构和实例连接。 对于初步发现的属性,检查这些属性是否系统使用的特征、是否描述了对象本身的特征、是否可以通过继承得到、是否可以从其他属性直接导出等,对这些属性进行整理和筛选。
在找到系统的对象类之后,我们需要分析和认识各类对象之间的关系,从而使对象类构成一个整体的、有机的系统模型。对象与外部的关系有以下几种: (1) 对象之间的分类关系,即泛化关系; (2) 对象之间的组成关系,即聚合关系; (3) 对象之间的静态关系,即关联关系; (4) 对象之间的动态关系,即依赖关系。发现泛化关系 我们可以参考应用领域已有的一些分类知识,也可以按照自己的常识,从各种不同角度考虑事物的分类,找出对象类之间的泛化关系。另外,通过考察系统中每个类的属性和服务,找出类之间的泛化关系。 * 查看一个类的属性与服务是否适合这个类的全部对象,如果某些属性或服务只适合该类的一部分对象,说明应该从这个类中划分出一部分特殊类,建立泛化关系; * 检查是否某些类具有相同的属性和服务,如果把这些相同的属性和服务提取出来,能否在概念上构成这些类的父类,形成泛化关系。 为了加强分析模型的可复用性,应该进一步考虑在更高的层次上运用泛化关系,从而开发一些可复用的构件类。发现聚合关系 聚合关系可以清晰地表达问题域中事物之间的组成关系,我们可以考虑以下方面建立聚合关系: * 物理上的整体事物和组成部分,如设备与零部件的关系; * 组织机构及其下级组织,如学校和系的关系; * 团体(组织)与成员,如学校和教师的关系; * 抽象事物的整体与部分,如法律与法律条文; * 具体事物及其某个抽象方面,如人员与身份。发现关联关系 关联关系表示对象之间的静态联系,即可以通过对象属性来表示的一个对象对另一个对象的依赖关系。在现实中存在大量的这种关系,如"教师"与"学生"之间的教学关系。我们可以通过以下分析活动,建立对象之间的关联关系: * 认识对象之间的静态联系,如"学生"与"课程"之间存在选课关系,那么这两个类存在关联关系; * 认识关联的属性和操作,如在"学生"和"课程"的连接中,需要给出开课学期、讲课教师等属性信息; * 分析关联的多重性,如"学生"和"课程"是多对多的连接; * 对于多元关联,需要增加一个对象类,使之转化为二元关联; * 对于多对多的关联,需要增加一个对象类,使之转化为两个一对多的关联。发现依赖关系 在面向对象的系统中,消息体现了对象行为之间的依赖关系,实现了对象之间的动态联系,使系统成为一个能活动的整体,并使各个部分能够协调工作。我们通过模拟和跟踪对象服务的执行过程,考虑当该对象执行时是否需要请求其它对象提供服务、是否需要向其他对象提供或索取某些数据等问题,从而建立依赖关系。
|
阅读全文(2060) | 回复(1) | 编辑 | 精华 |
回复:面向对象的分析 |
ssh(游客)发表评论于2010/6/23 14:15:47 | 很好!简单、明了,容易入门并付诸实践
|
个人主页 | 引用回复 | 主人回复 | 返回 | 编辑 | 删除 | » 1 »
|
« | August 2025 | » | 日 | 一 | 二 | 三 | 四 | 五 | 六 | | | | | | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | | | | | | | |
|
公告 |
有一种鸟儿是永远关不住的 因为它的每片羽翼上都沾满了自由的光辉
方向:计算机视觉 人工智能 演化算法
| |
Blog信息 |
blog名称:阳光海岸心 日志总数:166 评论数量:237 留言数量:-4 访问次数:1453077 建立时间:2006年6月2日 | |

|