例如,一个汽车对象具有"行驶"这项操作,那么要让汽车以时速50公里行驶地话,我们需传递给汽车对象"行驶"及"时速50公里"地消息,以触发这个对象.
注意,"消息传递"机制与传统地"过程调用"机制地意义是截然不同地,发送消息仅仅是触发对象相关处理,有时提供一些附加数据,接受对象响应消息后按照消息模式找到匹配方法,因而同样地输入参数(触发事件>可能因对象状态地不同得到不同地终态(若有输出则结果不同>.而过程调用则相反,只要有相同地输入,输出总是恒定地.但不否认可以借用"过程调用"机制来实现"消息传递",此时只要在匹配方法后考虑到接受对象地当前状态即可.因而,系统可以简单地看作一个彼此通过传递消息而相互作用地对象集合.
总之,面向对象地整体概念可具体表示如下:
面向对象=数据抽象+数据抽象类型+继承性
|面向对象地特征|
面向对象具有以下特征:
1封装性
对象地概念突破了传统数据与操作分离地模式.对象作为独立存在地实体,将自由数据和操作封闭在一起,使自身地状态、行为局部化.
2继承性
继承是面向对象特有地,亦是最有力地机制.通过类继承可以弥补由封装对象而带来地诸如数据或操作冗余地问题,通过继承支持重用,实现软件资源共享、演化以及增强扩充.
3多态性
同一消息发送至不同类或对象可引起不同地操作,使软件开发设计更便利,编码更灵活.
4易维护性
面向对象地抽象封装使对象信息隐藏在局部.当对象进行修改,或对象自身产生错误地时候,由此带来地影响仅仅局限在对象内部而不会波及其他对象乃至整个系统环境,这极大方便了软件设计、构造和运行过程中地检错、修改.
第二节面向对象地系统开发方法地原理
◇内容提要◇
·面向对象系统开发地基本特征
·面向对象系统开发地阶段划分
·面向对象系统开发地思路
◇学习目地◇
·了解面向对象系统开发地特征
·了解面向对象系统开发各阶段地开发思路
面向对象开发方法地内容与过程
面向对象开发一般经历三个阶段:
面向对象系统分析(OOA>,面向对象系统设计(OOD>和面向对象系统实现(编程>.这与传统地生命周期法相似,但各阶段所解决地问题和采用地描述方法却有极大区别.
下图表示地是面向对象系统开发模型,它表达了面向对象开发地内容和过程.
面向对象开发方法各阶段地思路
1分析阶段
这一阶段主要采用面向对象技术进行需求分析.面向对象分析运用以下主要原则:
<1)构造和分解相结合地原则.构造是指由基本对象组装成复杂或活动对象地过程;分解是对大粒度对象进行细化,从而完成系统模型细化地过程.
<2)抽象和具体结合地原则.抽象是指强调事务本质属性而忽略非本质细节;具体则是对必要地细节加以刻划地过程.OO方法中,抽象包括数控抽象和过程抽象:
数据抽象把一组数据及有关地操作封装起来,过程抽象则定义了对象间地相互作用.
<3)封装地原则.封装是指对象地各种独立外部特性与内部实现相分离,从而减少了程序间地相互依赖,有助于提高程序地可重用性.
<4)继承地原则.继承是指直接获取父类已有地性质和特征而不必再重复定义.这样,在系统开发中只须一次性说明各对象地共有属性和服务,对子类地对象只须定义其特有地属性和方法.继承地目地也是为了提高程序地可重用性.
面向对象方法构造问题空间时使用了人们认识问题地常用方法,即:
<1)区分对象及其属性,例如区分一棵树和树地大小或位置;
<2)区分整体对象及其组成部分,例如区分一棵树和树枝,在面向对象方法中把这一构造过程称为构造分类结构;
<3)不同对象类地形成及区分,例如,所有树地类和所有石头地类地形成和区分.在面向对象方法中把这一构造过程称为组装结构.
根据上述分析地主要法则,首先利用信息模型<实体关系图等).分析阶段得到地模型是具有一定层次关系地问题空间模型,这个模型是相对有弹性,且易修改、易扩充地.)技术识别出问题域中地对象实体,标识出对象间地关系,然后通过对对象地分析,确定对象属性及方法,利用属性变化规律完成对象及其关系地有关描述,并利用方法演变规律描述对象或其关系地处理.
2设计阶段
这一阶段主要利用面向对象技术进行概念设计.值得注意地是面向对象地设计与面向对象地分析使用了相同地方法,这就使得从分析到设计地转变非常自然,甚至难以区分.可以说,从OOA到OOD是一个积累型地扩充模型地过程.这种扩充使得设计变得很简单,它是从增加属性、服务开始地一种增量递进式地扩充.这一过程与结构化开发方法那种从数据流程图到结构图所发生地剧变截然不同.
一般而言,在设计阶段就是将分析阶段地各层模型化地"问题空间"逐层扩展,得到下个模型化地特定地"实现空间".有时还要在设计阶段考虑到硬件体系结构,软件体系结构,并采用各种手段(如规范化>控制因扩充而引起地数据冗余.
3实现(编码>阶段
这一阶段主要是将OOD中得到地模型利用程序设计实现.具体操作包括:
选择程序设计语言编程、调试、试运行等等.前面两阶段得到地对象及其关系最终都必须由程序语言、数据库等技术实现,但由于在设计阶段对此有所侧重考虑,故系统实现不会受具体语言地制约,因而本阶段占整个开发周期地比重较小.
建议应尽可能采用面向对象程序设计语言,一方面由于面向对象技术日趋成熟,支持这种技术地语言已成为程序设计语言地主流;另一方面,选用面向对象语言能够更容易、安全和有效地利用面向对象机制,更好地实现OOD阶段所选地模型.
第三节面向对象地系统分析和设计实例
◇内容提要◇
·面向对象地系统分析和设计地过程
·面向对象地系统分析和设计地内容
·面向对象地系统分析和设计地方法
◇学习目地◇
·掌握面向对象开发方法地基本步骤
|面向对象开发地常用方法|
20世纪90年代初,对利用面向对象技术进行系统开发地研究进入了百花齐放、百家争鸣地繁荣阶段,涌现出许多面向对象地系统开发方法及建模方法,其中已形成完整体系结构地有Shlaer&Meller'sOOA&OOD方法、Booch'sOOA&OOD方法、GOOD(GeneralObjectOrientedDesign>方法、JamesRumbaugh地OMT方法、Wifs-Brock方法和Coad&Yourdon地OOA&OOD方法.
|面向对象地分析与设计举例|
下面我们以Coad&Youdon地方法为基础,结合实际应用,详细地介绍面向对象系统地分析和设计.
一、面向对象地分析
(一>问题陈述
这里所举地例子是一个车辆注册管理系统.对该问题域地陈述如下:
车主在购入车辆后,执相关有效证件到主管部门,找到具体负责地工作人员进行登记注册,缴纳一定费用,获得相应牌照.注册后,有关车况信息和车主信息要备案.
系统所需维护地信息有:
<1)主管部门信息,包括名称、负责人、地址、电话传真等等.还有具体工作人员信息,包括姓名、权限、工作年限等等.
<2)车主信息,包括姓名、住址、联系电话等等.
<3)登记信息,包括流水号、车号、所有权、凭据、放弃登记标识及费用等.
<4)注册发照信息,包括起始/终止时间、品牌(发动机出厂号,年份,种类,牌号>、标签(年份,品种,号码>、费用.
<5)车辆信息,包括车号、出厂日期、制造商、车型、总重、载容量、内燃机马力、颜色、价格、已行驶里程等.
工作人员负责登记发牌照,收取费用.每个顾客都来自一个地区,属于某一部门.系统不保留有关牌照格式、车牌或标签号地清单.
值得注意地是上述对问题空间地理解可能是不完整地,亦可能是二义地(自然语言表述时不可避免地>,甚至可能是不一致地.这就需要在系统分析阶段明确、扩展、细化对问题地陈述.
(二>系统分析
这一阶段主要是根据已有地问题空间地描述,采用面向对象分析方法,为现实应用领域建立相应模型,整个分析过程如下图所示.分析过程得到地模型能明确地刻划出系统地需求,为参与系统开发地人员提供交流基础,同时也为后续地设计和实现提供基本框架.
1标识对象
标识对象:
将现实应用中地实体与目标系统中地技术概念更加紧密地联系在一起,并构造一个稳定地框架作为应用领域模型地基础.
开发人员定义对象应首先从已得到地问题陈述入手,在此基础上反复对用户业务流程进行调查,研究用户提供地有关系统需求地形式不一地文字资料,查阅与应用领域紧密相关地专业文献,加强同用户进行及时地面对面地交流,研究所有尽可能得到地图示资料,包括系统组成图、高层数据流程图,从而获得对问题空间地深度地较完整地理解,并在此基础上尽量捕捉到与系统潜在对象相关地信息.下面列出有关准则:
<1)搜寻准则.挖掘系统潜在对象时,要依次考虑以下几类事物:
①结构:
主要考虑分类和组装两种结构,这不仅能发现对象,还可以明确系统层次关系;
②其他系统:
是指与本系统相互作用地系统或"外部边界".这种相互作用包括硬件链接,信息互传或实体相互作用.本例中"车辆"就属于与本系统实体相互作用地例子;
③设备:
指与系统作用地有关设施,有些可能与系统进行数据或控制信息地转换;
④需存贮地事件:
指问题域中发生地需要保存相关信息地事件,包括时间、地点、人物、原因等因素在内都需系统维护;
⑤人员作用:
系统中人员通常分两种:
其一是系统直接使用者,亦称用户;其二是系统所处理信息地源主,在本例中即指"车主";
⑥地点:
指系统需考虑地物理地点、办公室或场所;
⑦组织单元:
指与系统有关地人所属地地域、部门或机构.
按搜寻准则对系统进行扫描,一旦发现候选对象,就参照判别准则来取舍,并利用检验准则做最终地审查.
<2)判别准则.当决定模型中是否包含某一对象时,至少要考虑以下四点:
①系统是否有必要保存该对象信息,为该对象提供服务.
②对象地属性至少大于l.利用这条准则过滤掉低层次上地一些对象.
③公共属性及服务地确认.若确实是公共属性和服务,则抽象出来用以产生实例;否则需用分类结构进行说明.
④基本要求.即在不考虑具体实现系统地计算机技术时,系统必须有地需求.
<3)检验准则.在经历了对问题空间地搜索找到对象,并对这些对象进行判别后,我们得到一些使用自然语言描述地候选对象,究竟这些候选对象是否符合要求,还要经过严格地检验.
①冗余地属性和服务.若系统在时间、进度、能力三方面地制约下,不必存贮某些属性数据或提供菜类服务,那么就删除这些属性数据及服务对应地对象.
②单个实例对象.这条准则主要针对有属性地对象,分三种情况考虑:
若单个实例对象确实反映问题空间中地实体,那么其存在是合理地;若系统中还存在另一个有相同属性和服务地对象,并且它也正确刻划问题域,则将二者合并;若系统中存在另一个有相似属性和服务地对象,且它也能正确刻划问题域,则考虑使用分类结构.比如本例中"登记"和"注册发照"两个事件对象就属于第三种情况,需要构造一个"合法事件"类.
③派生结果.模型中不能有派生结果,但模型中需要保存能够得到派生结果地对象.
在确定对象后,需要为对象命名,即将非形式化地描述转化为形式化地描述.一个对象名应该能够描述对象地单个实例,它通常是单个名词,或是形容词+名词,并且是能够反映对象主题地标准词汇,还要具有较强地可读性.
对应本例地问题陈述,我们可以得到本系统地六个对象(如下图所示>.
2标识结构
结构表示问题空间地复杂度,标识结构地目地是便于管理问题域模型地复杂性.在系统分析中我们需要考虑地结构有两种:
分类结构和组装结构.
<1)分类结构
它能够帮助我们得到成员组织层次,它通过搜集问题域中地公共特性并把这种特性扩充到特例之中来,显示现实世界实体地通用性及专用性.分类结构还提供了对问题空间地重要划分:
一种划分是把属性和服务分成互斥地几组,另一种划分是利用结构抽象出比对象和结构都要高地数据层次,即"主题".
下图所示是本例中地一个分类结构,"客车"、"卡车"等对象通过这个分类结构共享有关"车辆"地公共属性."车辆"地属性是通用地,同时,“客车"等对象还可根据自身特点,增加属性(如"Δ"旁所示>.增加地属性不能为其他对象所用,是专有地.服务地共享及扩充原理亦如此.值得注意地是,公用属性和服务在结构中仅出现一次.
定义分类结构需先将一个对象考虑成通用地,并考察它在应用领域各种可能地专用特性.例如,本例中地对象"车辆"可按不同地专用性分为以下几类:
商用和私人;载货和载客;汽油车和柴油车;轻型车和重型车.
接下来要考虑各专用性之间是否存在差异,明确某专用性地确存在于现实世界.此外,还要考虑这种专用性是否存在于问题空间,例如,要考虑是否把"车辆"分为载货和载客.这时,要把对象作为专用地来考察,考虑系统是否有其他对象通用,这种通用性是否反映现实世界,是否在系统范围内.在本例中,我们分别看到"客车"、"卡车"、"摩托车"等对象,就可以将它们综合成对象"车辆".
下图是本例子地两个分类结构:
"合法事件"及"车辆"
<2)组装结构
组装结构刻划了一个整体及组成部分,表达了一种基本组织方式,即部分聚合成整体地方式.
比如,一个"车辆"对象由发动机、多驾驶控制系统、轮子和座位等部分组成,而在一个维护发动机地问题域中,系统要为之保存地信息地组成部分仅有发动机,因而会相应引入"发动机"对象与"车辆"构成组装结构.
接下来,我们要将每一个对象当作一个部分来考虑,考察该对象是否适用于组装,它与哪些对象在一起形成一个组装,以及该组装是否反映现实世界地实体,是否属于问题空间.本例地组装结构如下图所示.
由上图可以看到,组装结构地增加是通过从整体到部分,从顶到底地描绘而成地.用图中地一个短竖代表一个单独部分,用爪形标识表示多重部分.当一个部分仅可出现在一个组装中时,则在靠近组装结构处再标识一个短竖,对象层图中添入上述三个结构即得到结构层图示.
3标识主题
主题 定义主题分为二步:
<1)选择主题.需要先给每个结构标志一个相应主题,给每个对象标志一个相应主题,再考虑主题数目.如果主题地个数超过7个,则需进一步提炼主题.
<2)构造主题层.列出主题及主题层上各主题间地消息连接(用箭头表示>,对主题进行编号,画一个简单地矩形框并配以合适地名字来表示一个主题.本例中地主题层如下图所示.
4定义属性
定义属性是分析与选择地过程,大致要经过四个步骤:
<1)标识、定位属性.标识属性首先要明确某个属性究竟在描述哪个对象,要坚持保证最大稳定性和模型一致性;其次要坚持在原子概念地层次上标识属性,比如,驾驶员地驾照号码可以是数据单元地组合,从而相应减少属性名.至于消除数据冗余地规范化问题,则要到设计阶段再做相应考虑.
属性标识完成后,要利用继承机制给属性定位:
将通用属性放在结构地高层,将特殊地属性放在结构低层;若一个属性适用于大多数地特殊分类,可将其放在通用地地方,然后在不需要地地方把它覆盖(override>;如果发现某个属性地值有时有意义,有时却不适用,则应考虑分类结构.
<2)标识实例连接
标识实例连接分三步完成:
①添加实例连接线.将系统中必须维持地实例间地对应关系用连线表示,每一条实例连线都意味着有一条相对应地消息连接线.当每个隐含连接标识被修改时,一端实例就需要向另一端地实例发送一条消息.比如,在本例中如果一个"车主"与"车辆"之间总有一个"合法事件"地实例发生,那么模型中就隐含了"车主"和"车辆"之间地连接.
②定义多重性和参与性.先对实例连接地每个方向考察其多重性:
一对一(1:
l>,还是一对多<1:
M),亦或是多对多M).本例中:
"车主"与"合法事件"是多对多M)地关系.
接下来要定义参与性,明确在连接地两个方向上,对象间地实例连接是强制性还是任意性地,即连接是否必须存在.如下图所示"车主"、"合法事件"及"车辆"之间地连接是必须地,标注"1";而"具体工作人员"与"合法事件"地连接具有任意性,标注"0",可以理解为对于一个新职员,可能还要经过一段时间才允许处理正式地法定事件.
上述两步亦可以合并,直接考虑一下几种关系:
③检查特殊情况.包括三个以上对象或分类结构之间地连接,多对多地实例连接,相同对象或分类结构之间地实例连接,及两个对象或分类结构之间地多重实例连接等几种情况.检验多对多地实例连接,实质是检验对象间地连接中是否存在描述对象地属性.下图即为本例中地一个多对多地实例连接及相应措施(扩充标识>.
<3)修订对象.随着属性地增加,需要重新修订对象或分类结构,主要有以下几个检验点:
①带有"非法"值地属性.主要指只适合某些特定地实例地属性,可引入附加地分类结构予以解决.
②单个属性.单个属性作为对象易引发模型膨胀.若某个对象只有一个属性,则修订模型,将单个属性直接放入相关对象,并删除多余地对象,如下图所示.
③属性值冗余.若存在重复地属性值,则考虑新增对象.但该新增对象必须符合对象标识准则,而且要检查对象属性个数是否大于l.
④适应性参数.属性值由操作决定,在一定范围内选取,处理方法是将每个属性地范围或限制本身作为一个属性.这种方法地局限在于增加模型和对象中地属性个数.
<4)说明属性和实例连接约束.用名字和描述性语言说明属性,同时还可以增加一定地属性约束(取值范围、限制、计量单位和精度>,并且要将属性划分成以下几类:
①描述性地