第 7章 信息系统开发新方法
7.1 原型开发方法
7.2 面向对象开发方法
7.3 标准建模语言( UML)简介
7.4 CASE开发方法
7.1 原型开发方法
7.1.1 原型方法的开发步骤原型开发方法是随着计算机软件技术的发展,特别是在关系数据库系统、第四代程序设计语言和各种系统开发生成环境的基础上,提出的一种从设计思想到工具、手段都全新的系统开发方法。
1,原型的概念原型开发方法首先由用户提出开发要求,开发人员识别和归纳用户要求,根据识别,归纳的结果,构造出一个原型,然后同用户一起评价这个原型 。 如果根本不行,则重新构造原型;
如果不满意,则修改原型,直到用户满意为止 。 这里所谓的原型 ( Protype),是目标系统的一个可执行模型或引导性的版本,
在需求分析和系统设计过程中用于开发人员与用户之间进行通信 。
原型开发方法通常要求能快速地构造出原型。原型的快速实现技术称为快速原型技术,目前一般采用计算机辅助原型开发技术。它需要有一个强有力的软件支撑环境,称为原型支持环境。通常原型开发方法所需要的软件支撑环境有:
① 一个方便灵活的关系数据库系统 ( RDBS) ;
② 一个与 RDBS相对应的快速查询系统,能支持任意非过程化的组合条件的查询;
③ 一套高级的软件工具 ( 如第四代语言或信息系统开发生成环境等 ),允许采用交互方式进行书写和维护以迅速产生任意程序语言的模块 ( 即原型 ) ;
④ 一个非过程化的报表或屏幕生成器,允许设计人员详细定义报表或屏幕输出样本 。
原型按照建立的目的不同可分为抛弃型原型和增量渐进型原型。
2,抛弃型原型抛弃型原型主要用于验证软件需求以及设计方案和算法,这是当前使用较广泛的原型 。 由于建立这类原型的目的在于使用户和开发人员较快地确定和建立需求,或者确定设计方案的可行性和其它技术性能,因而原型只集中于要验证的主要方面,而忽略其次要方面,以求得快速和少用资源 。 所以,许多因素如性能,错误处理以及其它质量因素一般均不予考虑 。 抛弃型原型不是一个完整的软件成分,验证后可抛弃不用 。
图 7.1为抛弃型原型开发方法的模型,图中各步骤的意义如下:
决定需求执行原型构造原型系统实现调整需求图 7.1 抛弃型原型开发模型
1) 决定需求这是决定用原型回答什么问题,典型问题有:
① 提出的系统行为适合用户需要吗?
② 系统输入输出界面可接受吗?
③ 提出的性能要求能满足吗?
2) 构造原型用手工或原型开发环境来构造原型 。
3) 执行原型由最终用户实际运行原型后,提出意见,并对需求进行调整,重新构造原型 。
4) 系统实现抛弃型原型只是作为开发过程的一种辅助工具,在用户需求确定后,
再按所采用方法实现目标软件的进一步开发 。
3,增量渐进型原型与抛弃型原型不同,建立增量渐进型原型的主要目的是要开发目标系统,而不只是为了满足需求和设计验证的需要 。 增量渐进型原型开发方法的工作步骤如下:
① 通过调查和可利用的文档,获得对用户需求的初始的理解;
② 基于已知的需求,构造一个快速原型;
③ 向用户演示原型,并让最终用户使用一个时期;
④ 从用户获得反馈,用此反馈修改已知需求;
⑤ 构造下一代原型,将用户的新需求结合进来;
⑥ 重复以上过程,直到新的应用系统开发结束并提交用户 。
增量渐进型原型开发模型使得原型方法由软件开发过程中的辅助工具发展成为一种软件开发方法 。
7.1.2 原型开发方法的特点原型方法具有如下几个方面的特点 。
(1) 原型方法更符合人们认识事物的规律,因而更容易被人们普遍接受 。
结构化方法在设计之前,要求人们能够精确地描述对目标系统的需求,这一点通常难以做到。人们认识任何事物都不可能一次完全了解,并把工作做得尽善尽美。
人们对于事物的描述,往往都是受到环境的启发而不断完善的。建立一个原型让用户来评价,提出改进的意见要比让用户空洞地描述对目标系统的设想更容易。
(2) 原型方法将模拟的手段引入系统分析的初期阶段,沟通了人们的思想,缩短了用户和分析人员之间的距离,解决了结构化方法中最难于解决的一个环节 。 通过原型可以启发用户对原来想不起来或不易准确描述的问题有一个比较确切的描述;能够及早暴露系统实现后存在的问题,促使人们在系统实现之前就加以解决 。
(3) 充分利用了最新的软件工具,使系统开发的时间,费用大大减少,效率,技术等都大大提高 。
当然,原型开发方法也不是万能的,它有其一定的适用范围和局限性。这主要表现在:
(1) 对于一个大型的系统,如果不经过系统分析来进行整体性划分,想要直接用屏幕来一个一个地模拟是很困难的 。 要想将原型开发方法应用于一个大型信息系统开发过程的各个环节是不可能的,因此,一般被用于小型局部系统或处理过程比较简单的系统设计到实现的环节 。
(2) 对于含有大量运算的逻辑性较强的程序模块,原型方法很难构造出模型来供认评价,因为这类问题缺少交互性,也不容易三言两语把问题说清楚 。
(3) 对于原基础管理不善、信息处理过程混乱的问题,使用原型开发方法有一定的困难。主要原因是工作过程不清,构造原型有一定困难;其次,由于基础管理不好,没有科学合理的方法可依,系统开发容易走上机械地模拟原来手工系统的轨道。
7.2.1 面向对象技术的发展过程
20世纪 70年代末至 80年代初,计算机应用领域日渐扩大,系统软件和应用软件的需求日益多样化,系统规模日益膨胀,传统的结构化分析方法和面向过程的编程技术已无法给予有效的支持,从而导致软件的生产方式和效率远远赶不上信息化社会发展的需要 。 人们开始寻找和研究新的方法和技术,面向对象方法和技术应运而生 。
面向对象 ( Object Orient,简称为 OO) 方法和技术起源于面向对象的程序设计语言 ( OOPL) 。 20世纪 80年代以来,大批 OOPL的出现和实用性,
效率的不断提高,标志着 OO技术开始走向繁荣和实用化 。
7.2 面向对象开发方法面向对象方法适合于解决分析与设计期间的复杂性并实现分析与设计的复用 。 从 20世纪 80年代中期开始,面向对象技术的焦点逐渐从程序设计转移到软件工程的其它阶段,面向对象分析与设计 ( OOA和 OOD) 技术得到了快速的发展,
初步形成新的方法论和开发技术 。
近年来又出现了一些新的高级技术,例如面向对象数据库、对象分布、对象总线、面向对象的系统框架构造以及面向对象的系统集成等。
7.2.2 面向对象方法的基本思想与用过程化方式描述应用系统的传统的结构化程序设计方法不同,面向对象的方法认为客观世界是由各种各样的对象组成的,每个对象都有各自的内部状态和运动规律,不同对象之间通过消息传送相互作用和联系就构成了各种不同的系统 。
将对象模型映射到计算机上,面向对象方法将软件系统看成是一系列对象的集合,并强调描述对象性质的数据及行为的紧密联系 ——数据和行为的封装技术 。 例如,学籍管理系统可以看成是由学生,教师,课程,各种规章制度等多个彼此独立而又相互关联的对象集合而成 。
面向对象的本质是确定动作的主体在先,而执行动作在后 。
这种面向对象的模式称为,主体 —动作,模式 。 例如,学生总是先选定某门课程,然后才去考虑如何学好这门课程 。 而在窗口系统的界面上,总是先选定一个界面对象 ( 图标或按钮 ),
然后在其上进行相应的操作 ( 例如移动,单击等 ) 。
反映面向对象本质的“主体 —动作”模式是与人们对客观世界的认识规律相符合的。因此,采用对象的观点看待所要解决的问题,并将其抽象为系统是极其自然与简单的,符合人类的思维习惯,应用系统也更容易被理解。“主体 —动作”模式的特点是将对象作为软件系统结构的基本组成单元,以主体数据为中心,对数据和作用在数据上的操作进行封装,以标准接口对外提供服务。
7.2.3 面向对象的基本概念
1,对象( Object)
对象是客观世界中事物在计算机领域中的抽象,是一组数据 ( 描述对象的特性或属性 ) 和施加于该组数据上的一组操作 ( 行为 ) 组成的集合体 。
例如,Windows 系统中窗口上的一个文本框对象包含有外部名
( Name),字体 ( Font),数据源 ( Data Source),前景颜色 ( Fore
Color),高度和宽度 ( Height Width) 等多种属性,同时还带有单击左键
( Click),双击左键 ( DoubleClick),修改文本 ( Change) 等多个操作 。
对象的属性可以是简单数据类型、结构数据类型,也可以是复杂数据类型(另一个对象)。例如,公司是对象,公司中包含有员工这一属性,而员工本身又是一个对象。
从系统的观点出发,可以给对象作如下定义:对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位,一个对象是由一组属性和对这组属性进行操作的一组服务构成的 。 属性是用来描述对象静态特征的一个数据项,也叫对象特性;服务是用来描述对象动态特征 ( 行为 ) 的一个操作;属性和操作称为对象的性质 。
当系统运行时,系统中的对象显现出其动态特征,即对象内部状态的转换和对象间的相互作用。例如,A对象向 B对象传送一个消息,这一消息附带的一个事件可能导致 B对象被激发或 B对象由于执行某一传送方所要求的操作,改变了某些内部属性值,从而由一个状态转入另一个状态(对象的一个状态是由某些内部属性值构成的)。
在面向对象系统中,对象之间的相互作用是通过消息传送来进行的 。
消息是向对象发出的服务请求,它应该含有下述信息:提供服务的对象标识,服务标识,输入信息和回答信息 。 消息通常由接收对象 ( 提供服务的对象标识 ),调用操作名 ( 服务标识 ) 以及必要的参数等三部分组成 。
消息的接收者是提供服务的对象,在设计该对象时,它对外提供的每个服务应规定消息的格式 ——消息协议 。 消息的发送者是要求服务的对象或其它系统成分,在每个发送点上,需要按服务方规定的消息协议写出一个完整的消息 。
当一个对象映射为软件实现时由三个部分组成:
(1) 私有的数据结构 。 它用于描述对象的内部状态 。
(2) 处理,称为操作或方法 。 它是施加于数据结构之上的 。
(3) 接口。这是对象可被共享的部分,消息通过接口调用相应的操作。
接口规定哪些操作是允许的;它不提供操作是如何实现的信息。
客观世界的同一对象在不同的应用系统中,由于考察对象的角度不同,对其抽象的数据结构和操作都可能是不同的。例如,对于一个学生,在学籍管理系统与户籍管理系统两个不同的应用系统中,抽象出的表示内部状态的数据结构和对数据结构进行的操作都是不同的。因此,在对实际应用系统中的对象进行分析时应注意该系统的要求,区分哪些是该对象的本质特征。
2,类与实例把具有共性的一些事物归为一类,是人们认识客观世界和分析问题的一般方法。这里的共性是指事物的本质特征,分类实际上是一种抓住事物的本质而忽略一些无关紧要的细节的抽象过程,例如图 7.2中从各种自行车到自行车类抽象。
自行车对象男车女车童车

抽象自行车类属性:
名称规格型号变速装置材料操作:
变速行走修理

图 7.2 各种自行车到自行车类的抽象同样,采用面向对象方法进行系统分析与设计时,对于一个具体的系统而言,可能存在很多具有相同特征的对象 。 例如,对于一个学籍管理系统,存在许多学生对象,它们具有相同的结构特征和行为特征,只是表示内部状态的数据值不同 。 为了描述这种相同结构特征和行为特征的对象,面向对象方法引入了类的概念 。
类是一组具有相同性质 ( 属性和操作 ) 的对象的抽象,或者说类是具有相同属性和服务的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和服务两个主要部分 。
类是对一组具有相同特征的对象的抽象描述,所有这些对象都是这个类的实例 。 对于学籍管理系统,学生是一个类,而一个具体的学生则是学生类的一个实例 。 一个类的不同实例具有相同的操作或行为的集合和相同的信息结构或属性的定义,但属性值可以不同;不同的实例具有不同的对象标识 。 对于学生类中的每一个对象,描述它们所使用的数据结构相同,但是其值不同 。
因此,一个类的定义至少包含以下两个方面的描述:
① 该类所有实例的属性定义或结构定义;
② 该类所有实例的操作 ( 或行为 ) 的定义 。
在一个系统中,每一个对象均属于某个类,类似对象的属性和操作的定义模板,而实例是某个具体的对象 。
7.2.4 面向对象系统的特性一个对象具有抽象,继承性,封装性和多态性等特性,要构造一个性能优越的面向对象系统必须充分利用面向对象方法的这些特性 。
1,抽象所谓抽象是指在分析问题时,强调实体的本质,内在属性而忽略一些无关紧要的细节 。 它是分析问题的基本方法 。
在系统开发的整个过程中,尤其在分析阶段,抽象具有特别重要的意义,其作用如下:
(1) 使用抽象仅仅涉及到应用域的概念而不必涉及问题域的求解,
因此可以尽可能避免过早地考虑实现的细节 。
(2) 合理地使用抽象,可以在分析,高级设计,程序结构,数据库结构以及文档化等阶段和过程中使用统一模型 ( 对象模型 ) 。
(3) 抽象可以帮助我们明确对象是什么,对象做什么而不必考虑对象怎么做 。
对象怎么做属于编程方面的细节,可以延迟到开发的最后阶段 —
—物理设计阶段去实现 。
2,继承性人们在对客观世界的事物进行描述时,经常采取分类的方法 。 类是有层次的,即某个大类的事物可能分为若干小类,而这些小类可能又分为若干个更小的类 。
面向对象思想采纳了事物分类的层次思想,在描述类的时候,某些类之间具有结构和行为的共性 。 例如,教师类与学生类在结构方面均具有姓名,年龄,身高,体重等共性,在行为 ( 或操作 ) 方面均具有回答身高,回答体重等操作 。 将这些共性抽取出来,形成一个单独的类 ——人,描述教师类和学生类中的共性 。 类人的结构特征和行为特征可以被多个相关的类共享 。 例如,教师类和学生类继承了类人的结构和行为特征 。 一个教师类的对象与一个学生类的对象都具有类人所描述的特征,同时又具有各自所属教师类和学生类独有的特征 。 此时类人称为教师类和学生类的父类,而学生类和教师类为类人的子类 。
上面例子中的类人也可以称为教师类和学生类的一般类,而教师类和学生类为类人的特殊类。面向对象方法中一般类和特殊类的定义是:
如果类 A具有类 B的全部属性和服务,而且具有自己特有的某些属性或服务,则类 A叫做类 B的特殊类,类 B叫做类 A的一般类。
利用类之间的继承关系,可以简化对类的描述 。 在类人中描述教师类和学生类的共性,而在学生类和教师类中只需描述各自的个性 。
利用继承机制可以提高软件代码的可重用性 。 在设计一个新类时,不必从头设计编写全部的代码,可以通过从已有的具有类似特性的类中派生出一个类,继承原有类中的部分特性,
再加上所需的新特性 。
这一点与面向过程的设计语言中的过程或函数不同,要使用具有相似功能的过程或函数必须修改源程序代码以使其适应新系统的功能需求,而类的派生机制无须原有类的源代码即可派生出新的类 。
利用类及其继承性描述系统时,由于类之间的继承关系,可能会形成一种具有层次性的类结构 。 在使用类的层次结构描述系统时,某些类之间的层次关系可以有多种实现方案 。 例如,中学生类既可以直接从类人派生出来,也可以从类人的派生类中学生类中派生出来 。 在设计类的层次结构时,应注意建立的类层次结构是否易于理解以及组织类结构的费用等方面的问题 。 设计出来的类层次结构是否合理,往往取决于系统分析员的经验等因素 。
另外,人们在对客观世界的事物分类时,一个事物可能属于多个类,
同时具有多个类的特性 。 例如,一个黑人学生,他既属于学生类,又属于黑人类 。 这种情形在面向对象方法中称为多继承,即一个类同时从多个类中派生出来,此时类的层次结构是网状的 。 多继承在有些面向对象的程序设计语言中是不允许的 。 只允许派生类有一个基类称为单继承,
单继承的类层次结构是树状的 。
3,多态性多态性是面向对象系统的又一重要特性 。 所谓多态是指一个名词可具有多种语义 。 在面向对象方法中,多态并不是指一个对象类有多种形态或状态,而是指同一个操作在不同的类中有不同的实现方法和不同的执行结果 。 例如,图 7.3中的图形类和其子类圆类,点类中都定义了显示和隐藏操作,
图形类中的显示和隐藏并不确定到底显示或隐藏何种图形,
但子类中的显示和隐藏就涉及到具体应该显示或隐藏何种图形,并且所显示的图形显然是不一样的 。 这就是显示和隐藏这两个操作体现出来的多态性 。 其特点是源于继承而并非简单的继承,必须有不同的表现 。
图形颜色中心点坐标显示隐藏移动点显示隐藏圆显示隐藏半径图 7.3 多态性的例子多态性不仅仅局限于操作,同一个属性在不同的对象类中也可以具有不同的数据类型,即属性的多态性 。
综上所述,多态性可定义为:,一个类中定义的属性或操作被继承之后,可以具有不同的数据类型或表现出不同的行为 。
这使得同一属性或操作在父类和子类 ( 或子类的子类,可多次继承 ) 中具有不同的语义 。,
就图 7.3中的例子而言,当外部的某个对象调用图形对象的显示操作时,无须考虑该操作具体对应多少种实现方法,即该对象发出的请求服务的消息中只需写上“显示”,究竟对应哪个显示由图形类的操作自动识别,并传给对应的子类,由子类去执行不同的显示操作,这也称为“动态绑定”。
4,封装性封装是一种信息隐藏技术,对象内部对用户是隐藏的,不可直接访问;
用户只能见到对象封装界面上的信息,通过对象的外部接口访问对象 。 用户向对象发送消息,对象根据收到的消息调用内部方法作出响应 。
封装的目的在于将对象的使用者和设计者分开,使用者无须知道对象内部实现的细节,只需要知道对象接收的消息 。
封装的定义为:
(1) 一个清楚的边界 。 所有对象的内部软件的范围被限定在这个边界内 。
(2) 一个接口 。 该接口用以描述这个对象和其它对象之间的相互作用 。
(3) 受保护的内部实现 。
因为封装技术强调客观实体的内在属性和服务(操作)的不可分割性以及内部信息的隐蔽,自然而然就增加了系统中对象的相对独立性,减少了它们之间的相互依赖,同时也增加了其应用的灵活性。
封装可以保证对象的界面清晰,简单,防止由于模块之间的相互依赖所带来的变动的相互影响 。 在非面向对象的系统中,如果某个函数的某些参数改变了 ( 类型,个数等 ),或者某些非私有数据改变了,
即使函数的外部功能没有改变,都要求调用该函数的其它模块必须随之作相应的改变,否则后果不堪设想 。 因为调用者可能会直接操纵被调用者中改变了的这些数据 。 相反,面向对象的封装性不允许一个对象直接操纵另一个对象的数据,即调用者无须知道被调用者的内部实现细节,所以只要外部功能没变,就不存在上述变动的相互影响 。 就比如甲,乙两人互送电子邮件,双方关心的是内容和格式是否符合要求,而不是电子邮件的素材,编辑工具以及传送方式 。
对象的封装特性可以提高模块之间的独立性,使得系统易于调试和维护 。 封装使得一个对象可以像一个可插接的部件一样用在各种程序中,就像一种集成块可以用在不同的电路中一样 。
7.2.5 面向对象的设计方法
(1) 定义问题 。
(2) 为现实世界问题域的软件实现开发一个不严格的概括描述 。
(3) 按以下子步骤把方法严格化:
① 弄清对象及其属性;
② 弄清可能被施于对象的操作;
③ 利用表达对象与操作的关系建立每个对象的接口;
④ 决定详细设计问题,从而给出对象的实现描述 。
(4) 递归地重复步骤( 1)、( 2)、( 3),以得到完整的设计。
面向对象设计方法将数据设计,结构设计和过程设计三类设计元素结合起来 。 为了弄清对象,产生了数据抽象;借助定义抽象,描述了模块,软件的结构也就建立起来了;靠开发使用对象的机制 ( 如生成消息 ),接口得到了描述 。
1,问题定义这里的问题定义是需求分析的另一种说法,此步骤中系统分析人员和设计人员应完成两项必不可少的工作:
① 描述问题本身;
② 分析并说明已知的限制 。
无论现实问题的大小和复杂性如何,其软件实现都应以语法正确的简单语句来描述,通过它应该让承担项目的软件工程师对问题有一个确切的,唯一的理解 。
2,概括描述这种概括描述具有以下几个特点:
① 它是简明易懂的一段文字描述;
② 它所涉及的对象具有同一级抽象的特点,即其详细程度在概括描述中保持一致;
③ 它应主要表达为解决问题必须要做什么,而不是如何得到解的过程;
④ 无须包括需求分析过程中所涉及的全部信息 。
3,形式化处理面向对象的设计经过前面的分析和描述后,到此实际上才展开 。 如前所述,形式化处理分以下几个步骤 。
1) 标识对象及其属性弄清对象是面向对象设计的核心问题,标识对象可以从应用系统的概括描述中的名词来导出。在这一步应把注意力集中在如何将概括描述中所含的名词和名词短语分离出来。
对象标识出来后,还应注意对象之间的类似之处,以建立对象类。
2) 标识每个对象所要求的操作和提供的操作这一步必须标识出该对象执行的功能,这些功能描述了每个对象的行为 。 例如窗口被打开,关闭,缩放和滚动等 。
同时还应关心由其它对象提供于它的操作,因为通过标识这些操作有可能导出新对象 。
3) 建立对象之间的联系和每个对象的接口这一步建立对象和对象类之间的联系,标识出每一个对象都与什么对象和对象类有关 。 这一步中可能找出一些对象的模式,并决定是否要建立一个新类以表示这些对象的共同行为特性 。
4) 建立每个对象的接口识别出系统中的对象和类以后还应该识别出对象之间的相互作用,
即对象的外部接口 。 在面向对象系统中,对象和对象之间的联系是通过消息的发送和响应来完成的 。
一旦对象,它们的操作,数据和对象间交互作用被了解,对象的实现就很容易用某种面向对象的语言来完成 。 面向对象设计方法是以上步骤反复进行,直到建立起完整软件设计的过程 。
上面介绍的 Booch的步骤是一种松散的、不十分严格的方法。其它一些主要的面向对象的设计技术还有 Rumbaugh提出的一种称为“对象模型技术
OMT”的设计方法,Alabiso提出的基于数据流分析的面向对象设计技术等。
7.2.6 面向对象程序设计语言简介
1,概述面向对象的设计技术需要面向对象的程序设计语言的支持,
面向对象的语言包含四个基本的分支:
(1) 基于 Smalltalk 的,包括 Smalltalk 的 五 个 版 本,以
Smalltalk-80为代表 。
(2) 基于 C的,包括 Objective-C,C++,Java。
(3) 基于 LISP的,包括 Flavors,XLISP,LOOPS,CLOS。
(4) 基于 PASCAL的,包括 Object Pascal,Turbo Pascal、
Eiffel,Ada 95。
在这些面向对象的语言中,术语的命名和支持面向对象设计的能力都有不同程度的差别 。 尽管 Smalltalk-80不支持多继承,它仍被认为是最具特征的面向对象语言 ( the truest OO language) 。
在基于 C的 OO语言中,Objective-C 是 Brad Cox开发的,它带有一个丰富的类库,已经被成功地用于大型系统的开发 。
C++语言是由贝尔实验室的 Bjarne Stroustrup开发的,它将 C语言中的结构体 ( struct) 扩展为具有数据隐藏功能的类 ( class) 。 多态性通过重载和虚函数 ( virtual functions) 来实现 。 C++语言支持多继承 。
在多数软件领域,C++都是首选的面向对象编程语言 。
同 C和 C++相类似的新一代基于因特网的面向对象语言 Java是由
Sun微系统研制的 。 它于 1995年伴随着 Internet的崛起而风靡一时 。 用
Java写的小程序 ( applets) 可以嵌入 HTML中被解释执行,这使它具备了跨平台特性 。 Java和 Ada一样支持多线程和并发机制,又像 C一样简单,便携 。
基于 LISP的语言,多被用于知识表达和推理的应用中 。 其中 CLOS
( Common LISP Object System) 是面向对象 LISP的标准版 。
在基于 Pascal的语言中,Object Pascal是由 Apple和 Niklaus Wirth为
Macintosh开发的,它的类库是 MacApp。 Turbo Pascal 是 Borland公司以
Object Pascal为范本开发的,Windows环境下的可视化开发工具 Delphi采用的就是 Object Pascal。
Eiffel由交互软件工程公司的 Bertrand Meyer于 1987年发布的 。 它运行于 Unix环境,其语法类似于 Ada。 Ada在 1983年刚出来时并不支持继承和多态性,因而不是面向对象的 。 到了 1995年,一个面向对象的 Ada
终于问世,这就是 Ada 95。
除了上述的面向对象的语言之外,还有一些语言被认为是基于对象 ( Object-based) 的 。 它们是,Alphard,CLU,Euclid,Gypsy、
Mesa,Modula等 。
2,C++语言的面向对象特性
C++是由贝尔实验室的 Bjarne Stroustrup设计的,它既保持了
C语言具有的高运行效率和可移植性,又克服了 C语言的缺点,
尤其是 C的类型检查能力方面的缺点 。 C语言在函数内部的类型检查能力很弱,在同一文件内各函数间也不能进行类型检查 。 除了少量差别外,可以将 C++看成是 C语言的超集 。
C++将 C语言中的 struct扩展为具有数据隐藏功能的类 class。
C++语言中的对象由描述对象属性的数据结构和作用于这个数据结构上的方法(或称为操作)构成,它们都可以分为私有的和公有的两个部分,私有部分从对象的外部不可直接访问,而公有部分可以由对象的外部访问。下面是一个 C++中类定义的例子:
class date{
int year;
int month;
int day;
public:
date();
date(int,int,int);
void getdate(char*);
void getdate(int *,int *,int *);
};
类的数据成员(如例子中的 year,month,day)描述对象的属性,函数成员(如例子中的 getdate)为作用于数据成员的方法。
定义一个指定类类型的变量即定义一个对象,例如:
date d;
定义一个 date类的对象 d。
C++中类的构造函数 ( 与类名同名的函数成员 ) 用于对对象进行初始化,对象创建时被隐含调用 。 在对象被销毁之前,可通过析构函数来完成一些整理工作 。
C++语言没有提供特别的消息机制,对象之间的相互联系和作用通过对公有数据成员和函数成员的访问来实现 。 例如:
d.getdate(s);
面向对象系统的继承性在 C++语言中通过类的派生机制来实现,可以从已有的类派生出一个新的类。这个新的类称为派生类,
原有的类称为基类。派生类可以继承基类的特性,也可以修改或屏蔽基类的特性。 C++支持多继承,即派生类可以有多个基类。
C++语言中的多态性主要体现在以下两个方面:
(1) 重载:在 C++语言中,同一函数名以及运算符可以具有不同含义的多种实现版本,编译器将根据函数调用的参数形式决定调用哪一种实现版本 。
(2) 虚函数,C++语言引入了虚函数机制,允许在不同类层次对象中应用函数成员的不同版本 。
例如实现一个类 Shape,然后从该类派生出画点的类 Point、画圆的类
Circle、画直线的类 Line,每一种图形的画法均不同,但是它们都有几种共同的操作:显示图形、擦除图形、移动图形。移动图形的操作都是首先擦除图形,然后改变图形的位置基准点,再在新位置显示出图形。移动图形的操作在类 Shape中实现,每种图形的显示、擦除、改变基准点等操作在派生类中分别实现。下面是 C++中 Shape,Point,Circle的声明:
class Shape{
int basex,basey; //基准点坐标
public:
virtual void show(); //显示图形,声明为虚函数
virtual void hide(); //隐藏图形,声明为虚函数
void move(int dx,int dy)//移动图形
{hide(); basex+=dx; basey+=dy; show(); }
};
class Point,public Shape{ //从 shape类派生出 Point类
public:
void show();
void hide();
};
class Circle,public Shape{ //从 shape类派生出 Circle类
int radius;
public:
void show();
void hide();
};
7.3 标准建模语言( UML)简介
7.3.1 UML概述面向对象的分析与设计方法的发展在 20世纪 80年代末至
90年代中期出现了一个高潮,UML是这个高潮的产物。它统一了 Booch,Rumbaugh等的表示方法,并且对其作了进一步的发展,最终统一为大众所接受的标准建模语言。
1,标准建模语言 UML的发展历史早期的面向对象建模语言出现于 20世纪 70年代中期,到 90年代初,数量从不到 10种增加到了 50多种 。 虽然不同建模语言的创造者都努力推崇自己的产品,并在实践中不断完善,但是由于用户并不了解不同建模语言的优缺点及相互之间的差异,因而很难根据应用特点选择合适的建模语言,于是爆发了一场,方法大战,。 90年代中期,一批新方法出现了,其中最引人注目的是
Booch 1993,OOSE和 OMT-2等 。
Booch是面向对象方法最早的倡导者之一,他提出了面向对象软件工程的概念 。 1991 年,他将以前面向 Ada的工作扩展到整个面向对象设计领域 。 Booch 1993比较适合于系统的设计和构造 。
Rumbaugh等人提出了面向对象的建模技术 ( OMT) 方法,
采用了面向对象的概念,并引入各种独立于语言的表示符 。 这种方法用对象模型,动态模型,功能模型和用例模型,共同完成对整个系统的建模,所定义的概念和符号可用于软件开发的分析,
设计和实现的全过程 。 软件开发人员不必在开发过程的不同阶段进行概念和符号的转换 。 OMT-2特别适用于分析和描述以数据为中心的信息系统 。
Jacobson于 1994年提出了 OOSE方法,其最大特点是面向用例
( Use-Case),并在用例的描述中引入了外部角色的概念。用例的概念是精确描述需求的重要武器,贯穿于整个开发过程,包括对系统的测试和验证。 OOSE比较适合支持商业工程和需求分析。
另外,还有 Coad/Yourdon方法,即著名的 OOA/OOD,
它是最早的面向对象的分析和设计方法之一 。 该方法简单,
易学,适合于面向对象技术的初学者使用,但由于该方法在处理能力方面的局限,目前已很少使用 。
1994年 10月,Grady Booch和 Jim Rumbaugh开始致力于这一工作 。 1995年秋,OOSE 的创始人 Ivar Jacobson加盟到这一工作 。 第一个公开版本,称为统一方法 UM 0.8
( Unitied Method) 。 1996年 6月和 10月又分别发布了两个新的版本,即 UML 0.9和 UML 0.91,并将 UM重新命名为 UML
( Unified Modeling Language) 。
1996年成立了 UML成员协会,以完善,加强和促进 UML的定义工作 。 当时的成员有 DEC,HP,I-Logix、
Itellicorp,IBM,ICON Computing,MCI Systemhouse、
Microsoft,Oracle,Rational Software,TI以及 Unisys等 。
这一机构对 UML 1.0( 1997年 1月 ) 及 UML 1.1( 1997年
11月 17日 ) 的定义和发布起了重要的促进作用 。 图 7.4描述了 UML的发展历程 。
公众反馈
9 7,1 1,1 7
U M L 1,1 被 O M G
接纳为标准
9 7,9 公布
U M L 1,1
9 7,1 公布
U M L 1,0
9 6,6 和 9 6,1 0 U M L 0,9 & 0,9 1
O O P S L A 9 5 U n if ie d M e t h o d 0,8
合作伙伴意见其它方法
B o o c h 9 3 O M T - 2
B o o c h 9 1 O M T - 1 O O S E
工业化标准化统一化分散的各部分图 7.4 UML的发展历程
UML是一种定义良好,易于表达,功能强大且普遍适用的建模语言 。 它融入了软件工程领域的新思想,新方法和新技术,支持从需求分析开始的软件开发的全过程 。
UML融合了 Booch,OMT和 OOSE等方法中的基本概念,但又不仅仅是上述方法的简单汇合,而是在这些方法的基础上集众家之长,几经修改而完成的,它扩展了现有方法的应用范围 。
UML已获得了工业界、科技界和应用界的广泛支持,已有
700多个公司表示支持采用 UML作为建模语言,它已成为可视化建模语言事实上的工业标准。 1997年 11月 17日,OMG组织采纳
UML 1.1作为基于面向对象技术的标准建模语言。 UML代表了面向对象方法的软件开发技术的发展方向,具有巨大的市场前景,
也具有重大的经济价值和国防价值。
2,标准建模语言 UML的主要特点标准建模语言 UML的主要特点可以归结为三点,
(1)?UML统一了 Booch,OMT和 OOSE等方法中的基本概念 。
(2)?UML吸取了面向对象技术领域中其它流派的长处,其中也包括非
OO方法的影响 。 UML符号考虑了各种方法的图形表示,删掉了大量易引起混乱的,多余的和极少使用的符号,也添加了一些新符号 。 因此,在 UML
中汇入了面向对象领域中很多人的思想 。
(3)?UML在演变过程中还提出了一些新的概念。在 UML标准中新加了模板( Stereotypes)、职责( Responsibilities)、扩展机制( Extensibility
mechanisms)、线程( Threads)、过程( Processes)、分布式
( Distribution)、并发( Concurrency)、模式( Patterns)、合作
( Collaborations),活动图( Activity diagram)等新概念,并清晰地区分类型( Type),类( Class)、实例( Instance)、细化( Refinement)、接口( Interfaces)和组件( Components)等概念。
UML以面向对象图的方式来描述任何类型的系统,具有很宽的应用领域 。 最常用的是建立软件系统的模型,但它同样可以用于描述非软件领域的系统 。 UML适用于系统开发过程中从需求规格描述到系统完成后测试的不同阶段 。 如何恰当地将这种可视化图形建模技术用于解决软件开发所面临的问题,如何研制和开发支持 UML的建模过程及其支持环境,仍是目前该领域的热点问题 。
目前,在基于 UML的开发方法和环境方面,国际上已经进行了一些研究和实际开发工作 。 Rational 公司正致力于它称之为
Objectory过程的研究,并试图将其原有支持 OMT的工具作进一步扩充,以支持 UML建模 。 国内对 UML支持环境的研制开发工作尚处于起步阶段 。
7.3.2 UML静态建模机制简介任何建模语言都以静态建模机制为基础,标准建模语言 UML也不例外 。 UML的静态建模机制包括用例图 ( Use case diagram),类图 ( Class diagram),对象图 ( Object diagram),包 ( Package),
构件图 ( Component diagram) 和配置图 ( Deployment diagram) 。
7.3.2.1 用例图长期以来,在面向对象开发和传统的软件开发中,人们一直用典型的使用情景来描述需求 。 但是,这些使用情景是非正式的,难以规范化描述 。 用例模型由 Ivar Jacobson在开发 AXE系统中首先使用,并加入由他所倡导的 OOSE和 Objectory方法中 。 用例方法引起了面向对象领域的极大关注,面向对象领域已广泛接纳了用例这一概念 。
1,用例模型 ( Use case model)
用例模型用于需求分析阶段,描述的是外部执行者 ( Actor) 所理解的系统功能 。 它的建立是系统开发者和用户反复讨论的结果,表明了开发者和用户对需求规格达成的共识 。
用例模型描述了待开发系统的功能需求,将系统看作黑盒,从外部执行者的角度来理解系统 。 它驱动了需求分析之后各阶段的开发工作,
不仅在开发过程中保证了系统所有功能的实现,而且被用于验证和检测所开发的系统,从而影响到开发工作的各个阶段和 UML 的各个模型 。
在 UML中,一个用例模型由若干个用例图描述,用例图主要元素是用例和执行者 。
2,用例 ( use case) 与执行者 ( Actor)
一个用例从本质上讲是用户与计算机之间的一次典型交互作用 。 例如,在文字处理软件中,,将某些正文置为黑体,和
,创建一个索引,便是两个典型的用例 。 执行者是指用户在系统中所扮演的角色 。
UML将用例定义成系统执行的一系列动作,动作执行的结果能被指定执行者察觉到 。 图 7.5是一个图书管理系统的用例图的一部分,其中的椭圆表示用例,小人表示执行者 。
用例捕获用户的需求,实现一个具体的用户目标,它由执行者激活,并提供确切的值给执行者。它是对一个具体的用户目标实现的完整描述。
B o r r o w C o p y
o f B o o k
R e t u r n C o p y
o f B o o k
B o o k B o r r o w e r
B o r r o w C o p y
o f J o u r n a l
R e t u r n C o p y
o f J o u r n a l
J o u r n a lB o r r o w e r
图 7.5 用例图
3,通信联系图 7.5中,不带箭头的线段将执行者与用例连接到一起,表示两者之间交换信息,称之为通信联系 。 执行者触发用例,并与用例进行信息交换 。 单个执行者可与多个用例联系;反过来,一个用例可与多个执行者联系 。 对同一个用例而言,不同执行者有着不同的作用:他们可以从用例中取值,也可以参与到用例中 。
执行者在用例图中是用类似人的图形来表示,但执行者未必是人。例如,执行者也可以是一个外界系统,该外界系统可能需要从当前系统中获取信息,与当前系统进行交互。
4,使用和扩展 ( Use and Extend)
用例图除了包含执行者与用例之间的连接外,还可以有另外两种类型的连接,用来表示用例之间的使用和扩展关系 。
使用和扩展是两种不同形式的继承关系 。 当一个用例与另一个用例相似,但所做的动作多一些,就可以用到扩展关系 。 当有一大块相似的动作存在于几个用例,又不想重复描述该动作时,就可以用到使用关系 。
用例用来获取需求,规划和控制项目 。 用例的获取是需求分析阶段的主要任务之一,而且是首先要做的工作 。 大部分用例将在项目的需求分析阶段产生,并且随着工作的深入会发现更多的用例,这些都应及时增添到已有的用例集中 。 用例集中的每个用例都是一个潜在的需求 。
对一个大系统,要列出用例清单常常十分困难。可先列出执行者清单,
再对每个执行者列出它的用例,问题就会容易很多。
7.3.2.2 类图,对象图和包类 ( Class),对象 ( Object) 和它们之间的关联是面向对象技术中最基本的元素 。 对于一个想要描述的系统,其类模型和对象模型揭示了系统的结构 。 UML用类图和对象图分
1,类图类图 ( Class Diagram) 描述类和类之间的静态关系 。 它不仅显示了信息的结构,同时还描述了系统的行为 。 类图是定义其它图的基础 。 在类图的基础上,状态图,合作图等进一步描述了系统其它方面的特性 。
保险单
D a t e R e c ie v e d
is P r e p a id
n u m b e r,S t r in g
p r ic e,M o n e y
d is p a t c h ( )
c lo s e ( )
客户客户名,S t r in g = 缺省客户名地址,S t r in g
取客户名地址 ( 客户名,S t r in g ) S t r in g
属于签定
1
保险单上的项目
Q u a n it y,I n t e g e r
P r ic e,M o n e y
is S a t if ie d,B o o le a n
*
团体客户
C o n t a c t N a m e
c r e d it R a t in g
c r e d it L im it
r e m in d ( )
b illf o r M o n t h ( I n t e g e r )
个体客户
c r e d it C a r d #
保险类别
1
*
图 7.6 类图
UML中类的图形表示为一个划分成三个格子的长方形 ( 下面两个格子可省略 ) 。 图 7.6中的,客户,就是一个典型的类 。
最顶部的格子包含类的名字,类的命名应尽量用应用领域中的术语,应明确,无二义性,以利于开发人员与用户之间的相互理解和交流 。
中间的格子包含类的属性,用以描述该类对象的共同特点 ( 该项可省略 ) 。 图 7.6中,客户,类有,客户名,,,地址,等属性 。
底部的格子表示该类的操作 ( Operation) 。 该项也可省略 。 操作名,返回类型和参数表组成操作界面 。
定义了类之后,就可以定义类之间的各种关系了。类之间的关系主要有以下几种:
1) 关联关系关联 ( Association) 表示两个类之间存在某种语义上的联系 。 在图 7.6中最上部存在一个,属于,/“签定,关联:每个,保险单,属于一个,客户,,
而,客户,可以签定多个,保险单,。
关联可以有方向,表示该关联单方向被使用 。 关联上加上箭头表示方向,在 UML中称为导航 ( Navigability) 。 只在一个方向上存在导航表示的关联称作单向关联 ( Uni-directional Association),在两个方向上都有导航表示的关联称作双向关联 ( Bi-directional Association) 。 图 7.6中,,保险单,
到,保险单上的项目,是单向关联 。 UML规定,不带箭头的关联可以意味着未知,未确定或者该关联是双向关联三种选择,因此在图中应明确使用其中的一种选择 。
双向关联可以在每个方向上给出一个名字,可以用小黑三角表示名字的方向,例如图 7.6中最上部的,属于,/“签定,关联 。
关联两头的类以某种角色参与关联。例如图 7.7中,“公司”以
“雇主”的角色,“人”以“雇员”的角色参与的“工作合同”关联。“雇主”和“雇员”称为角色名。如果在关联上没有标出角色名,则隐含地用类的名称作为角色名。
公司人
1 *
雇主 雇员工作合同角色名关联名多重性图 7.7 关联的角色角色具有多重性 ( Multiplicity),表示可以有多少个对象参与该关联 。 在图 7.7中,雇主 ( 公司 ) 可以雇佣 ( 签工作合同 ) 多个雇员,表示为,*”,雇员只能与一家雇主签定工作合同,表示为
,1”。 多重性表示参与对象的数目的上下界限制 。,*” 代表 0~ ∞,
,1”是 1..1的简写 。 多重性可以用一个单个数字表示,也可以用范围或者是数字和范围不连续的组合表示 。
一个关联可能要记录一些信息,可以引入一个关联类来记录 。
图 7.8是在图 7.7的基础上引入了关联类 。 关联类通过一根虚线与关联连接 。
公司 人
1 *
雇主 雇员工作合同合同期限:年关联类图 7.8 关联类
2) 聚集 ( Aggregation) 关系聚集是一种特殊形式的关联,表示类之间是整体与部分的关系 。 例如,
一辆轿车包含四个车轮,一个方向盘,一个发动机和一个底盘 。 在需求分析中,,包含,,,组成,,,分为 …… 部分,等经常设计成聚集关系 。
聚集可以进一步划分成共享聚集 ( Shared Aggregation) 和组成 。 例如,
课题组包含许多成员,但是每个成员又可以是另一个课题组的成员,即部分可以参加多个整体,称为共享聚集 。 另一种情况是整体拥有各部分,部分与整 体 共 存,如 整 体 不 存 在 了,部 分 也 会 随 之 消 失,这 称 为 组 成
( Composition) 。 例如,我们打开一个窗口,就可见它由标题,外框和显示区所组成,窗口一旦消亡则各部分同时消失 。 在 UML中,聚集表示为空心菱形,组成表示为实心菱形 。
3) 继承关系在 UML中,继承表示为一头为空心三角形的连线。如图 7.6中,将客户进一步分类成个体客户和团体客户,使用的就是继承关系。
4) 依赖关系假设有两个元素 X,Y,如果修改元素 X的定义可能会引起对另一个元素 Y的定义的修改,则称元素 Y依赖 ( Dependency) 于元素 X。
在类中,依赖由各种原因引起,如:一个类向另一个类发消息;一个类是另一个类的数据成员;一个类是另一个类的某个操作参数 。 如果一个类的界面改变,它发出的任何消息可能不再合法 。
5) 类图的细化 ( Refinement)
细化是 UML中的术语,表示对事物更详细一层的描述。两个元素 A、
B描述同一件事物,它们的区别是抽象层次不同,若元素 B是在元素 A的基础上的更详细的描述,则称元素 B细化了元素 A,或称元素 A细化成元素 B。
细化的图形表示为由元素 B指向元素 A一头为空心三角的虚线。
2,对象图,对象和链
UML中对象图与类图具有相同的表示形式 。 对象图可以看作是类图的一个实例 。 对象是类的实例;对象之间的链 ( Link) 是类之间的关联的实例 。 对象与类的图形表示相似,均为划分成两个格子的长方形 ( 下面的格子可省略 ) 。
上面的格子是对象名,对象名下有下划线;下面的格子记录属性值 。 链的图形表示与关联相似 。 对象图常用于表示复杂的类图的一个实例 。
3,包 ( Package)
将许多类集合成一个更高层次的单位,形成一个高内聚、
低耦合的类的集合,UML中称为包,通过这种方法可以将大系统拆分成小系统。在 UML中,包图主要显示类的包以及这些包之间的依赖关系。有时还显示包和包之间的继承关系和组成关系。图 7.9是一个包图的例子。
保险单填写界面保险单 客户数据库界面
O r a c l e
界面
S y b a s e
界面包系统内部包的依赖包的继承图 7.9 包图主要还有以下模型符号和概念:类别模板
( Stereotype ),界面 ( Interface ),参数化类
( Parameterized Class) 或称为模板类 ( Template),限定关联 ( Qualified Association ),多 维 关 联 ( N-ary
Association),多维链 ( N-ary Link),派生 ( Derived),
类型 ( Type) 和注释 ( Note),约束 ( Constraint) 等 。
类图可以说是所有 OO方法的支柱。采用标准建模语言
UML进行建模时,必须对 UML类图引入的各种要素有清晰的理解。
7.3.2.3 构件图和配置图构件图 ( Component diagram) 和配置图 ( Deployment
diagram) 显示系统实现时的一些特性,包括源代码的静态结构和运行时刻的实现结构 。 构件图显示代码本身的结构,
配置图显示系统运行时刻的结构 。
构件图显示软件构件之间的依赖关系。一般来说,软件构件就是一个实际文件,可以是源代码文件、二进制代码文件和可执行文件等。构件图可以用来显示编译、链接或执行时构件之间的依赖关系。
配置图描述系统硬件的物理拓扑结构以及在此结构上执行的软件 。 配置图可以显示计算结点的拓扑结构和通信路径,结点上运行的软件构件以及软件构件包含的逻辑单元 ( 如对象,类 )
等 。 配置图可以帮助用户理解分布式系统 。
结点 ( Node) 代表一个物理设备以及运行于其上的软件系统,如一台 Unix主机,一个 PC终端,一台打印机,一个传感器等 。 如图 7.10所示的配置图中,,客户端 PC”和,保险后台服务器,就是两个结点 。 结点表示为一个立方体,结点名放在左上角 。
结点之间的连线表示系统之间进行交互的通信路径,在
UML中称为连接( Connection)。通信类型则放在连接旁边的
,《》,之间,表示所用的通信协议或网络类型。
在配置图中,构件代表可执行的物理代码模块,如一个可执行程序 。 逻辑上它可以与类图中的包或类对应 。 因此,配置图中显示运行时各个包或类在结点中的分布情况 。 如在图 7.10
中,,保险后台服务器,结点中包含,保险系统,,,保险对象数据库,和,保险系统配置,3个构件 。
在面向对象方法中,类和构件等元素并不是所有的属性和操作都对外可见。它们对外提供了可见操作和属性,称之为类和构件的界面。界面可以表示为一头是小圆圈的直线。图 7.10
中,“保险系统”构件提供了一个“配置”界面。配置图中还显示了构件之间的依赖关系,“保险系统配置”构件依赖于这个“配置”界面。
客户端 PC
保险单填写界面保险系统保险对象数据库保险系统配置配置保险政策配置用户保险后台服务器配置构件中包含的对象结点连接构件的界面构件
》,T C P / I P
图 7.10 配置图标准建模语言 UML的静态建模机制是采用
UML进行建模的基础。熟练掌握基本概念、区分不同抽象层次以及在实践中灵活运用,是三条最值得注意的基本原则。
7.3.3 UML动态建模机制简介
UML的动态建模机制通过状态图,顺序图,合作图和活动图来实现 。 这四个动态模型中均用到面向对象技术中消息这个概念 。
同步消息异步消息简单消息图 7.11 消息的类型
UML定义的消息类型有三种:
(1) 简单消息 ( Simple Message),表示简单的控制流,用于描述控制如何在对象间进行传递,而不考虑通信的细节 。
(2) 同步消息 ( Synchronous Message),调用者发出消息后必须等待消息返回,只有当处理消息的操作执行完毕后,调用者才可继续执行自己的操作 。 操作的调用是一种典型的同步消息 。
(3) 异步消息 ( Asynchronous Message),当调用者发出消息后不用等待消息的返回即可继续执行自己的操作,主要用于描述实时系统中的并发行为 。
1,状态图 ( State Diagram)
状态图用来描述一个特定对象的所有可能状态及其引起状态转移的事件 。 大多数面向对象技术都用状态图表示单个对象在其生命周期中的行为 。 一个状态图包括一系列的状态以及状态之间的转移 。
1) 状态所有对象都具有状态,状态是对象执行了一系列活动的结果 。
当某个事件发生后,对象的状态将发生变化 。 状态图中定义的状态有初态,终态,中间状态,复合状态 。 其中,初态是状态图的起始点,而终态则是状态图的终点 。 一个状态图只能有一个初态,而终态则可以有多个 。
L o gi n
e nt r y/ t ype,l o gi n,
e xi t / l o gi n( use r na m e,pa ss w d)
do/ g e t use r na m e
图 7.12 一个带有动作域的状态一个状态可以进一步地细化为多个子状态,我们将可以进一步细化的状态称为复合状态。子状态之间有“或关系”和“与关系”两种关系。或关系(如图 7.13所示)说明在某一时刻仅可到达一个子状态。
例如,一个处于行驶状态的汽车,在“行驶”这个复合状态中有向前和向后两个不同的子状态,在某一时刻汽车要么向前,要么向后。与关系(如图 7.14所示)说明复合状态中在某一时刻可同时到达多个子状态(称为并发子状态)。具有并发子状态的状态图称为并发状态图。
行驶向前 向后图 7.13,或关系”的子状态行驶向前 向后低速 高速图 7.14 一个具有并发子状态的状态图
2) 转移状态图中状态之间带箭头的连线称为转移。状态的变迁通常是由事件触发的,此时应在转移上标出触发转移的事件表达式。如果转移上未标明事件,则表示在源状态的内部活动执行完毕后自动触发转移。
2,顺序图 ( Sequence Diagram)
顺序图用来描述对象之间动态的交互关系,体现对象间消息传递的时间顺序 。 顺序图存在两个轴:水平轴表示不同的对象,垂直轴表示时间 。
顺序图中的对象用一个带有垂直虚线的矩形框表示,并标有对象名和类名 。 垂直虚线是对象的生命线,用于表示在某段时间内对象是存在的 。
对象间的通信通过在对象的生命线间画消息来表示。消息的箭头指明消息的类型。图 7.15是一个顺序图的例子。
a M e m b e r,B o o k B o r r o w e r
L ib r a r y M e m b e r
t h e L ib r a r y M e m b e r
:
t h e C o p y,C o p y t h e B o o k,B o o k
b o r r o w ( t h e C o p y )
1,o k T o B o r r o w
2,b o r r o w
2,1,b o r r o w e d
图 7.15 顺序图
3,合作图 ( Collaboration Diagram)
合作图用于描述相互合作的对象间的交互关系和链接关系 。 虽然顺序图和合作图都用来描述对象间的交互关系,但侧重点不一样 。
顺序图着重体现交互的时间顺序,合作图则着重体现交互对象间的静态链接关系 。
合作图中对象的外观与顺序图中的一样。如果一个对象在消息的交互中被创建,则可在对象名称之后标以 {new}。类似地,如果一个对象在交互期间被删除,则可在对象名称之后标以 {destroy}。对象间的链接关系类似于类图中的联系(但无多重性标志)。通过在对象间的链接上标志带有消息串的消息(简单、异步或同步消息)
来表达对象间的消息传递。
1) 链接链接用于表示对象间的各种关系,包括组成关系的链接
( Composition Link),聚集关系的链接 ( Aggregation Link),限定关系的链接 ( Qualified Link) 以及导航链接 ( Navigation Link) 。 各种链接关系与类图中的定义相同,在链接的端点位置可以显示对象的角色名和模板信息 。
2) 消息流在合作图的链接线上,可以用带有消息串的消息来描述对象间的交互。消息的箭头指明消息的流动方向。消息串说明要发送的消息、消息的参数、消息的返回值以及消息的序列号等信息。
4,活动图 ( Activity Diagram
C a c u la t e t o t a l c o s t
C h a r g e a c c o u n t G e t a u t h o r iz a t io n
[ c o s t < $ 5 0 ]
[ c o s t > = $ 5 0 ]
图 7.16 活动图的例子
7.4.1 软件开发技术的发展历史软件开发环境和工具是为了提高软件开发的生产率而引进的,它的诞生是与软件开发技术的发展以及软件工程概念的出现密切相关的 。
7.4 CASE开发方法
1) 个体生产时期
2) 软件作坊时期
3) 软件工程时期从 20世纪 40年代计算机出现后,软件开发技术一直伴随着硬件技术的发展而发展,大致经历了如下三个阶段:
软件作坊时期又称为,软件 =程序 +说明,时期,这个时期出现了商品化的通用软件,大约从 60年代初到 70年代初 。 这个时期程序规模不断扩大,一个项目往往需要有多人分工协作,共同完成,程序开发者之间必须遵守一致的约束规范 。
这个时期对程序的可读性,可理解性要求提高,要求程序必须有注解和说明,以便于程序开发者之间通信和协作交流 。
这个时期从 70年代至今。这个时期计算机硬件技术突飞猛进,计算机软件的应用范围越来越广,软件的复杂程度也越来越高,传统的软件开发技术越来越不能适应软件需求增长的速度,在 60年代末期产生了所谓的软件危机。
1968年北大西洋公约组织的计算机科学家在原联邦德国召开的会议上正式提出了,软件工程,这个术语 。 软件工程从诞生发展至今,可分为两个时期 。
第一个时期称为软件工程方法时期,这个阶段从 70年代初到 80年代中期,出现了不少指导软件开发的方法,例如生命周期模型、结构化分析与设计方法、技术审查、技术复审等。这些方法是有效的,但是这些方法的实施以手工为主,许多工作是复杂而很费人工的。为了解决这个问题,不断开发出一些计算机软件作为辅助实施软件工程的方法的工具,
这种技术被称为计算机辅助软件工程技术( Computer Aided Software
Engineering,简称 CASE)。但这个时期的工具软件往往是各自开发的,
工具之间不具备兼容性,即一个工具的输出信息不能作为另一个工具软件的输入数据。而且每个工具往往只适用于软件开发过程的某一个阶段,
缺乏对全过程的支持,而且通常只适用于单一的软件开发模型。
第二个时期是集成的计算机辅助软件工程时期
( Integrated CASE,简称 ICASE) 。 这个时期从 80年代中期到现在,它的特点是使用集成的计算机辅助软件开发环境 。 这类软件开发环境支持多种软件开发模型 ( 例如瀑布流模型,快速原型模型等 ) 与多种软件开发方法
( 如结构化分析与设计方法,Jackson方法,面向对象方法等 ),对软件生存周期提供全过程的支持 。 ICASE
的使用使得软件开发的质量和生产率得到大大的提高,
开创了软件工程的新局面 。
7.4.2 CASE开发方法的基本思路从上面的叙述可以知道,采用 CASE工具辅助开发并不是一种真正独立意义上的方法,不过就目前 CASE工具的发展和它对整个开发过程的支持来说,又不失为一种实用的系统开发方法 。
CASE方法解决问题的基本思路是:如果在对系统调查后,
系统开发过程的每一步都可以形成一定的对应关系 ( 例如,结构化开发方法从数据流程图到软件结构图,再到软件模块的逻辑结构的过程 ),则可以借助于特定的 CASE工具软件来实现上述一个个的系统开发过程 。
由此可见,使用 CASE开发方法必须依赖于某一种具体的开发方法,对常见的一些开发方法,如结构化方法,原型方法,面向对象方法等,一般大型的 CASE工具都可以支持 。
另外应该注意的是,CASE只是一种辅助的开发方法,
它的辅助作用主要体现在它能帮助开发者方便快捷地产生出系统开发过程中各类程序和文档 。
由于在实际开发过程中,各个步骤之间可能只是在一定程度上对应,而不是绝对的一一对应,因此 CASE工具不可能一次“映射”得到最终结果,还需要有开发人员的干预。
7.4.3 CASE技术简介
CASE自 80年代出现以来,得到了较快的发展:从早期支持需求分析,
功能分析,生成各种结构化图表 ( 如数据流程图,结构图等 ) 的工具和辅助开发环境发展到目前不仅支持结构化开发方法,原型方法,而且还支持面向对象方法以及知识处理语言的大型软件综合开发环境 。 它是工具和方法相结合的产物 。
CASE的优秀代表产品有 DEC公司的 Digital Cohesion,Oracle公司的
Oracle CASE Method等 。
CASE系统的结构通常如图 7.17所示,以 CASE库为中心。 CASE库是一个分布式多用户的资料库,可帮助开发人员收集、管理、存储开发中的信息,自动定义格式,综合开发过程中的资料并进行分析验证。
C A S E
库用户用户
C A S E 工具图 7.17 CASE示意图
CASE工具是指 CASE系统的最外层 ( 用户 ) 使用 CASE去开发一个应用系统时,所接触到的软件工具 。 这一层次的软件很多,
各家公司的系统也不尽相同,各有所长 。 归纳起来,大致可分为以下几类:
① 图形工具 。 绘制结构图,生成系统专用图;
② 屏幕显示和报告生成的各种专用系统;
③ 专用检测工具 。 测试错误与不一致性的专用工具;
④ 代码生成器 。 从原型系统的工具中自动产生程序代码;
⑤ 文档生成器。产生结构化方法和其它开发方法所需的各种文档。
7.4.4 CASE开发方法的特点与其它开发方法相比,CASE方法具有以下一些特点:
① 解决了客观世界到软件系统的直接映射的问题;
② 使结构化方法更加实用;
③ 自动检测的方法大大提高了软件的质量;
④ 使原型方法和面向对象方法付诸实施;
⑤ 简化了软件管理与维护;
⑥ 使开发者从繁琐的分析设计图表和程序编写工作中解放出来;
⑦ 软件成分的可重用性提高;
⑧ 产生出统一的标准化的系统文档;
⑨ 使软件开发的速度得到了很大的提高。