第一节 面向对象方法基本概念
第二节 面向对象的软件工程方法
第六章 面向对象方法学概述
60年代末出现的软件危机使人们认识到应该
采用工程的概念、原理、技术和方法来开发与维
护软件。传统的结构化方法曾经给软件产业带来
了巨大的进步,在一定程度上解决了软件的可靠
性、可生产性和可维护性等方面的问题,部分地
缓解了软件危机。但在开发大型软件时,采用结
构化方法开发的软件在稳定性、可修改性、可维
护性等方面仍然存在许多问题,面向对象方法是
近年来发展起来的能够解决这些问题的一个非常
实用而强有力的软件开发方法。
第一节 面向对象方法基本概念
一, 面向对象方法的发展
面向对象( Object Oriented)方法的形成最
初是从面向对象程序设计语言( Object
Oriented Program Language,简称 OOPL)开始
的,随之才逐渐形成面向对象分析和设计方法。
80年代中期,C++语言十分热门的时候,面向对
象分析( Object Oriented Analysis,简称 OOA)
的研究开始发展,进而延伸到面向对象设计
( Object Oriented Design,简称 OOD)的研究。
面向对象
程序设计语言
面向对象
分析和设计方法
90年代以后,OOA/OOD方法逐渐走向实用,一
些专家按照面向对象思想,对系统分析和系统设
计工作的步骤、方法、图形工具等进行了详细的
研究,提出了许多不同的实施方案:
比较著名的有 Coad/Yourdon的方法,Booch的
方法和 Rumbaugh的 OMT方法等,它们在实践中使
用较多。
至此,面向对象方法从理论走向了具体实现。
面向对象方法已经深入到计算机科学技术的
许多领域,除上面所说的程序设计语言和系统分
析外,还应用在数据库、计算机辅助设计工程、
人 -机界面设计、计算机辅助教学( CAI)、多媒
体技术、计算机网络等诸多领域。
二, 面向对象开发技术的基本思想
现实世界中的问题在结构上是由一些实体所
组成, 实体之间相互联系, 相互作用 。
例如, 我们的环境由许多实体如人, 树, 汽
车, 房子, 街道等组成, 这些实体之间相互发生
作用构成我们的环境 。
面向对象中,用, 对象, 来描述组成现实世
界的实体,对象之间通过传递, 消息, 互相联系
来模拟现实世界中不同实体彼此之间的联系。
面向对象方法中,任何事物都是对象,复杂
的对象可以由相对简单的对象以某种方法组成,
甚至整个世界也可以从一些最原始的对象开始,
经过层层组合而成。
运用面向对象方法解决现实世界中复杂问题
的方法,就是将现实世界中的问题从组成结构上
自然分解成一个个对象,用对象及对象之间的联
系建立起问题域的模型。
这种分解方式同传统的从功能角度对问题进
行分解的方法完全不同,它对现实世界的描述更
加直接并且更符合人类的思维方式。
三, 面向对象方法的基本概念
在面向对象方法中以下这些概念的使用具有
一致性。也就是说,不仅在面向对象分析及面向
对象设计中一致地使用这些概念,而且在实现阶
段如果采用面向对象语言来实现,那么也完全支
持这些概念的实现。
(一 )对象
对象是面向对象开发技术的核心,是现实世
界中实体的映射。
对象可以是有形的(如一架飞机),也可以
是无形的(如一项规划)。
现实世界中实体的特征包括 静态的数据特征
和 动态的行为特征,就好象我们在认识了解某一
个人时,不会将他的静态特征(例如性别、身高、
年龄等)与动态特征(例如如何说话、如何走路
等)特意分开,两者结合在一起才能完整体现出
这个人。
属性:
性别:男;
身高,170CM;
体重,75KG;
对象名,ZHANG
操作:
回答身高;
回答体重;
对象定义为由一组数据和施加于该组数据上的一组操
作组合的集合体。
每 个 对 象
有 一 个 唯
一 标 识 的
对象名 。
数据一
般称之
为属性
,属性
用来描
述对象
静态特
征 。
对象的操
作也称之
为服务或
行为,
操作用来
描述对象
动态特征

面向对象技术中,通过对象的属性和操作
来完整地、自然地描述现实世界中的实体。
对象的选取和对象中应该具有哪些属性和操
作由特定的问题领域来决定,同样是, ZHANG”:
在某个问题域中,可以看成是消费者,他的属性
可能是信誉史、消费概况、住址等;再换一个问
题域,他可能是汽车驾驶员,他的属性可能是事
故历史、违章记录、保险金额等。
(二 )类及实例
采用面向对象方法进行系统分析与设计时,
对于一个具体的系统而言,可能存在许多对象彼
此相似。
例如,张三、李四、王五虽说每个人性别、
身高、体重等各不相同,但是属性特征和操作特
征是相似的。
为了描述对象的这种相同的特征,引入, 类,
的概念。
类 就是对具有相同属性和相同操作的一组相
似对象的定义,也就是说,在类中包含两组定义:
属性的定义和操作的定义。
1.属性的定义 就是说明属性值所属的类
型, 该类型限定了属性的取值范围和允许的运算
规则;
2.操作的定义 分成两部分:操作的规格
说明 ( 说明属于该类的对象能够进行哪些操作以
及操作的方式 ) 和操作的过程说明 ( 说明属于该
类的对象如何进行这些操作 ) 。
例如引入类, People”的说明。在该类定义
的基础上,可以具体说明三个对象, ZHANG”、
,LI”,,WANG” 属于该类的实例,在确定三个
对象的属性值时必须遵守该类的属性定义,否则
系统指出错误,同样对象所能进行的操作以及操
作的过程也只能遵守该类中的操作定义。
类,People
属性说明:
性别:字符型( ‘ m’为, 男, ; ‘ f’为,女, );
身高:整型(以 CM为单位);
体重:整型(以 KG为单位);
操作说明:
回答身高;
回答体重;
对象,ZHANG
属性:
性别,‘ m’;
身高,170;
体重,75;
操作:
回答身高;
回答体重;
对象,WANG对象,Li
属性:
性别,‘ f’;
身高,165;
体重,55;
属性:
性别,‘ m’;
身高,180;
体重,75;
操作:
回答身高;
回答体重;
操作:
回答身高;
回答体重;

实例
(三 )消息
消息是对象之间的联系,消息具有发送者和
接收者。发送者应该发送什么消息给接收者?发
送的消息应该如何表达?接收者对发给自己的消
息应不应该接收?接收以后作些什么?这些通过
将类中用来与外部发生联系的操作的规格说明对
外开放(注意只是操作的规格说明开放,操作的
过程是隐藏的)来实现,这些规格说明描述了该
类的对象所能接收的消息以及消息的格式。
对象在接收到某个消息后就执行相应的操作,
在执行相应操作的过程中,如果需要也可以发送
消息请求其它对象来完成某些操作。总之,现实
世界中实体之间的相互联系和相互通信,在面向
对象中通过消息的传递来实现,从而完成各种功
能。
(四 )封装
对象中封装的概念可以和集成电路芯片作类
比。一块集成电路芯片由陶瓷封装起来,其内部
电路是不可见的,也是使用者不关心的。芯片的
使用者只关心芯片引脚的个数、引脚的电气参数
以及引脚提供的功能,通过这些引脚,硬件工程
师对这个芯片有了全面的了解。硬件工程师将不
同的芯片引脚连在一起,就可以组装一个具有一
定功能的产品。而软件工程师也是通过使用对象
来努力达到这个目的。
内部的虚线表明对象的属性对于该对象的各
个操作是共享的,外部的实线表明对象属性的具
体细节(例如某个属性的数据类型是什么?)以
及操作实现的具体细节隐藏在对象的内部,外部
只能通过消息与对象联系,获取对象的信息。
属性
操作 1 操作 2
操作 3…
对象的封装
数据结构
函数 1
函数 3
函数 2

结构化的实现
消息
消息
消息
封装是对象的一个基本特征,封装使对象具
有更高的独立性。通过比较结构化方法的实现和
面向对象方法的实现,可以清晰体会对象封装的
特点。
结构化的实现,通过定义一个数据结构描述
静态特征,用函数(或过程)实现他的操作,这
些函数共享数据。这与对象似乎相同,但是结构
化方法中不存在一种机制来控制对数据的访问,
任何一个其它的函数都可以访问该数据;而在对
象中,对属性的访问被封闭在对象的内部。
例如:对于对象, ZHANG”,外部也许知道它
有一个属性, 身高,,但不知道, 身高, 的具体
细节(数据类型、单位等),更不能直接访问,
只能通过发消息询问, ZHANG”,而, ZHANG”接到
消息回答。
(五 )继承性
某些类之间具有结构和行为特征的共性,例
如教师和学生,在结构(或属性)方面均具有年
龄、身高、体重等,在行为(或操作)方面均具
有回答身高、回答体重等操作,这些与一般的人
相同。但是教师和学生又有自己的特殊属性和操
作。于是,我们在类, People”的基础上,派生
出, Teacher”类和, Student”类。利用类之间的
继承关系,在一般类中描述共性,在特殊类中只
描述教师和学生的个性,简化了类的描述。
类,People
属性说明:
性别:字符型( ‘ m’为, 男, ; ‘ f’为, 女” );
身高:整型(以 CM为单位);
体重:整型(以 KG为单位);
操作说明:
回答身高;
回答体重
类,Student
属性说明:
所教课程:字符串(不超过 10)
操作说明:
回答所在年级;
类,Teacher
属性说明:
所教课程:字符串(不超过 10)
操作说明:
回答所教课程;
由此,我们得到继承性的含义:如果类 B继承
类 A,那么,类 A中的所有属性和方法均成为类 B
的组成部分。同时称类 B为类 A的子类、类 A为类 B
的父类。
继承性的突出特点在于:
1.使系统的修改或维护局部化 。 例如, 当
我们修改, People”类的属性或操作后, 这种修
改将自动被继承到, Teacher”类和, Student”类
中, 在, Teacher”类和, Student”类中无需作任
何工作 。
2.可以有效地避免系统结构的冗余, 有利
于简化系统描述 。 例如, 由于, People”类描述
了, Teacher”类和, Student”类的共性, 使得
,Teacher”类和, Student”类的描述大为简化,
而只需描述其个性 。
利用类继承性描述系统时,由于类之间的继
承关系,可能会形成一种具有层次性的类结构。
也就是说,在类结构中的某一个类可能是从其父
类采用继承的方法派生而来,同时,该类又可能
被其子类继承,从而形成层次性的类结构。
四, 面向对象的优点
结构化技术的本质是功能分解,从代表目标
系统整体功能的单个处理着手,自顶向下不断地
把复杂的处理分解成子处理,子处理再进行分解
直至分解出来的子处理的功能已经十分简单。然
后通过一个个模块(过程或函数)来实现各个处
理功能。整个系统的结构是由实现处理功能的模
块来构成。
然而用户需求的变化大部分是针对功能的,
这种功能的需求变化往往造成系统结构的不稳定。
另外,传统的结构化方法将数据与过程作为相互
独立的实体,数据用于表达实际问题中的信息,
程序用于处理这些数据。程序员在编程时必须时
刻考虑所要处理的数据格式,对于不同的数据格
式即使要作同样的处理或者对于相同的数据格式
但要作不同的处理,都必须编写不同的程序。这
种情况使得传统开发的软件很难修改,可重用程
度低,维护非常困难。
与结构化方法相比,面向对象方法有以下优
点:
1.稳定性 面向对象的软件系统的模型是根
据问题领域的实体结构建立起来的, 而现实世界
中的实体结构是相对稳定的, 所以整个系统结构
也是相对稳定 。
2.容易修改 用户的大部分需求变化是针对
功能, 而功能被封装在某个对象之中, 所以当系
统中某些功能发生变化, 往往仅需要对某个对象
作一些局部性的修改, 并不会引起软件结构的整
体变化 。
3.可重用性好 首先对象类固有的封装性
使对象内部的实现与外部隔离, 具有较强的独立
性, 是比较理想的可重用的软件成分;其次面向
对象的继承性使类在重用时存在很大的灵活性,
子类不仅可以重用父类的属性和操作, 而且可以
在父类的基础上方便地修改和扩充, 这种修改并
不影响对原有类的使用 。 因此, 可以像使用集成
电路 ( IC) 构造计算机硬件那样, 比较方便地重
用对象类来构造软件系统 。
4.可维护性好
首先面向对象的技术符合人们习惯的思维
方式, 用这种方法所建立的软件系统的结构与问
题空间的结构基本一致, 因此比较容易理解;
其次面向对象软件稳定性好, 修改只需在
局部进行;
第三面向对象软件的维护主要通过从已有
类派生出一些新类来实现, 维护后的测试和调试
工作主要围绕这些新派生出来的类进行, 而类是
一个独立性很强的模块, 向类的实例发消息即可
运行它, 观察它是否正确地完成它的工作, 因此
对类的测试容易实现, 发现的错误也往往集中在
类的内部, 容易调试 。 这些因素都使得用面向对
象技术开发的软件可维护性好 。
第二节 面向对象的软件工程方法
面向对象的软件工程方法是面向对象方法在
软件工程领域的全面运用。它包括:
面向对象分析( OOA)
面向对象设计( OOD)
面向对象的编程( OOP)
面向对象测试( OOT)
面向对象软件的维护
一, 面向对象的分析 ( OOA)
众所周知,在解决问题之前必须首先理解所
要解决的问题。为了更好地理解问题,人们常常
采用建立问题模型的方法。所谓模型,就是为了
理解事物而对事物作出的一种抽象,是对事物的
一种无歧义的书面描述。通常,模型由一组图示
符号和组织这些符号的规则组成,利用它们来定
义和描述问题域中的术语和概念。
用面向对象方法成功地开发软件的关键,同
样是对问题域的理解。 OOA通常要建立三个模型,
它们分别是描述系统组成的 对象模型,描述系统
控制结构的 动态模型 和描述系统功能的 功能模型 。
这三种模型都涉及都到数据、控制和操作等共同
的概念,只不过每种模型描述的侧重点不同,三
种模型综合起来则全面地反映了对目标系统的需
求。
当解决的问题不同时,这三个模型的重要程
度也不同。几乎解决任何一个问题,都需要从客
观世界实体及实体间相互关系抽象出极有价值的
对象模型;当问题涉及交互作用和时序时(例如,
用户界面及过程控制等),动态模型就显得十分
重要;解决运算量很大的问题(例如,高级语言
编译、科学与工程计算等),则涉及功能模型。
动态模型和功能模型中都包含了对象模型中对象
的操作。
二, 面向对象的设计 ( OOD)
OOA与 OOD的职责划分是,OOA针对问题域运用
OO方法,建立一个反映问题域的 OOA模型,不考
虑与系统实现有关的因素(包括编程语言、图形
用户界面、数据库等等),从而使 OOA模型独立
于具体的实现。 OOD则针对系统的一个具体的实
现运用 OO方法。
其中包括两方面的工作,一是把 OOA模型直接
过渡到 OOD(不经过转换,仅作某些必要的修改
和调整),作为 OOD的一个部分;二是针对具体
实现中的人机界面、数据存储、任务管理等因素
补充一些与实现有关的部分。这些部分采用与
OOA相同的表示法和模型结构。
OOA与 OOD采用一致的表示法是面向对象的分
析和设计优于传统的软件工程方法的重要因素之
一。这使得从 OOA到 OOD不存在转换,只有一些局
部的修改或调整,并增加几个与实现有关的独立
部分。因此 OOA与 OOD之间不存在传统方法中分析
与设计之间的鸿沟,两者能够紧密衔接,大大降
低了从 OOA过渡到 OOD的难度、工作量和出错率。
三, 面向对象的编程 ( OOP)
认识问题域与设计系统成分的工作已经在 OOA
和 OOD阶段完成,OOP工作就是用一种编程语言把
OOD模型中的每个成分书写出来。理想的 OO开发
规范,应要求在 OOA和 OOD阶段对系统需要建立的
每个对象类及其内部构成(属性和服务)与相互
关系(结构和静态、动态联系)都达到透彻的认
识和清晰的描述,而不是把许多问题遗留给程序
员去重新思考。程序员需要动脑解决的工作主要
是:用具体的数据结构来定义对象的属性,用具
体的语句来实现服务流程图所表示的算法。
四, 面向对象的测试 ( OOT)
OOT是指:对于用 OO技术开发的软件,在测试
过程中继续运用 OO技术,进行以对象概念为中心
的软件测试。
采用 OO技术开发的软件含有大量与 OO方法的
概念、原则及技术机制有关的语法与语义信息。
在测试过程中发掘并利用这些信息,继续运用 OO
的概念与原则来组织测试,可以更准确地发现程
序错误并提高测试效率。
主要原因是:
( 1)在用面向对象编程语言( OOPL)编写的
程序中,对象的封装性使对象成为一个独立的程
序单位,只通过有限的接口与外界发生关系,从
而大大减少了错误的影响范围。 OOT以对象的类
作为基本测试单位,查错范围主要是类定义之内
的属性和服务,以及有限的对外接口(消息)所
涉及的部分。
( 2)有利于 OOT的另一个因素是对象的继承
性,对父类测试完成之后,子类的测试重点只是
那些新定义的属性和服务。( 3)如果利用面向
对象语言编程时,由于在 OOA—— OOD—— OOP中
概念的一致性,OOT还可以通过捕捉 OOA/OOD模型
信息,检查程序与模型不匹配的错误。这一点是
传统的软件工程难以达到的。
五, 面向对象的维护
软件维护的最大难点在于人们对软件的理解
过程中所遇到的障碍。维护人员往往不是当初的
开发人员,读懂并正确地理解由别人开发的软件
是件困难的事情。在用传统的软件工程方法开发
的软件中,各个阶段的文档表示不一致,程序不
能很好地映射问题域,从而使维护工作困难重重。
面向对象的软件工程方法为改进软件维护提
供了有效的途径。程序与问题域一致,各个阶段
的表示一致,从而大大降低了理解的难度。无论
是发现了程序中的错误而逆向追溯到问题域,还
是需求发生了变化而从问题域正向地追踪到程序,
道路都是比较平坦的。面向对象方法可提高软件
维护效率的另一个重要原因是,将系统中最容易
变化的因素(功能)作为对象的服务封装在对象
的内部。而对象的封装性使一个对象的修改对其
它部分的影响变小,从而避免了波动效应。