面向对象的软件开发方法
第9章 面向对象的软件开发方法
掌握:面向对象的开发方法、UML、常用的
UML视图、面向对象的分析与设计、面向对象 的编程、面向对象的软件测试。
9.1 面向对象方 法概述
9.1.1 面向对象的由来与基本概念 1. 面向对象的由来 面向对象的思想最初可追溯到20世纪60年代开 发的Simula 67语言,一般将它当作面向对象 语言的鼻祖。 20世纪70年代出现的Ada语言是支持数据抽象 类型的最重要的语言之一。 后来出现的Smalltalk语言是最有影响的面向对 象的语言之一,它丰富了面向对象的概念。 20世纪80年代中期以后,面向对象的程序设计 语言开始广泛应用于程序设计,并出现了更多 的面向对象的语言,如Object-C,C++, Java等。
面向对象首先体现为一种思想,可简要概括如下: (1)客观世界由对象组成,任何客观实体都是对象,复 杂对象可以由简单对象组成。 (2)具有相同数据和操作的对象可归纳成类,对象只是 类的一个实例。 (3)类可以派生出子类,子类除了继承父类的全部特性 外还可以有自己的特性。 (4)对象之间的联系通过消息传递来维系。类的封装性 使其具有某些对外界不可见的数据,这些数据只能通 过消息请求调用可见方法来访问。 简单地说,面向对象=对象+类+继承+消息。
2.对象 对象是面向对象开发方法的核心。 一般认为,对象就是一种事物,一个实体,从 最简单的整数到极其复杂的控制系统等都可被 看作是对象。 举例来说,飞机、车辆、桌子、计算机等有形 的实体,医生、职工、学生、公司等人或组织, 计划、安排、演出、开会等事件和活动,都可 以被当作是某种对象。
3. 类 类是对象的集合的一种抽象,它描述的是一类对象的 共同的性质和行为,其中性质用属性表达,行为用方 法描述。 例如,“人”就可被当作一个类,具有性别、身高、 体重、肤色等属性,同时,具有开门、走路、吃饭、 喝水等方法,这是所有“人”都具备的共同的性质和 行为。每一个具体的“人”是该类的对象。 类概念的提出在面向对象思想发展中具有极其重要的 作用。 类具有一些十分重要的特性,包括继承、封装和多态。
4. 继承
图9-1 类的继承
图9-2 单重继承和多重继承
5.封装 把某个类的共同的属性和方法“组装起来”称为对象 类的封装,或称为信息隐蔽。封装的含义是某个对象 类的共同的属性和方法,对该类中的某一对象来讲是 信息隐蔽的,这个对象只能见到封装界面上的信息, 即接口。类的封装同芯片的封装很相似,其内部的 “电路”是不可见的。 6.多态 对象之
间的调用是通过消息来完成的。在收到消息时, 对象要予以响应。不同的对象收到同一消息可产生完 全不同的结果,这一现象叫做多态。
7.类的关系 系统中的类与类之间存在着各种关系,例如前 面所讲的“继承”(又称为“泛化”,它表示 类与类之间、接口与接口之间的继承关系,或 类对接口的实现关系)。除此之外,常见的类 的关系还包括:
1)关联 关联是一种结构化的关系,指一种对象和另 一种对象有联系。对于两个相对独立的对象, 当一个对象的实例与另一个对象的一些特定实 例存在固定的对应关系时,这两个对象之间为 关联关系。
Class Employee{ public void DoWork(); } Class Association{ private Employee myEmployee; public void DoSomething(){ myEmployee.DoWork(); } }
2)依赖 依赖是指一个类使用了另一个类,它是一种 使用关系,即一个事物的规格说明的变化可能 会影响到使用它的另一个事物(反之不一定)。 最常见的依赖关系是一个类中使用了另一个类 的定义。对于两个相对独立的对象,当一个对 象负责构造另一个对象的实例或者依赖另一个 对象的服务时,这两个对象之间主要体现为依 赖关系。
Class DependReturnType{ }
Class DependParameter{ }
Class DependVarible{ } Class Depend{ public DependReturnType Test (DependParameter param){ DependVarible var = new DependVarible(); return new DependReturnType(); } }
3)聚合 当对象A被加入到对象B中,成为对象B的组成部分 时,对象B和对象A之间为聚合关系。聚合是一种较强 的关联关系,强调的是整体与部分之间的关系。例如, 计算机类和外设类的关系。 4)组合 组合是一种特殊的聚合关系,它是一种强类型的聚 合,组合中的部分不能脱离整体而独立存在,例如汽 车类和汽车轮胎类之间的关系。 组合与聚合的区别在于:在生命周期的实现上,组 合需要负责其部分的创建和销毁,聚合不需要;组合 中的一个对象在同一时刻只能属于一个组合对象,而 聚合的一个部分对象可以被多个整体对象聚合,例如 一个学生可以在多个学校就读,而一个菜单在同一时 刻只能是某个窗口内的对象。
8.消息 消息是对象之间的通信联系,它表现了对象行为的 动态联系。通常,一个对象向另一个对象发出消息请 求某项服务时,接收消息的对象响应该消息,激活所 要求的服务操作,并将操作结果返回给请求服务的对 象。
9.1.2 面向对象的开发方法 1.Booch方法 Booch方法是由Grady Booch 提出的一种 开发方法,它最先描述了面向对象的软件开发 方法的基础问题,指出面向对象开发是一种根 本不同于传统的功能分解的设计方法。面向对 象的软件分解更接近人对客
观事务的理解,而 功能分解可通过问题空间的转换来获得。 Booch方法的过程包括以下步骤: (1)在给定的抽象层次上识别类和对象。 (2)识别这些对象和类的语义。 (3)识别这些类和对象之间的关系。 (4)实现类和对象。
2.Coad/Yourdon方法 Coad/Yourdon方法也称为OOA/OOD方法。 Coad/Yourdon方法严格区分了面向对象分析OOA 和面向对象设计OOD。该方法利用5个层次和活动定 义及记录系统行为、输入和输出。这5个层次的活动包 括: (1)发现类及对象。 (2)识别结构。 (3)定义主题。 (4)定义属性。 (5)定义服务。
3.OMT方法 OMT方法是1991年由James Rumbaugh等5人提 出来的,其经典著作为《面向对象的建模与设计》。 Rumbaugh的OMT方法提供了3种模型,即对象模 型、动态模型和功能模型。 对象模型描述对象的静态结构和它们之间的关系, 主要的概念包括: 类、属性、操作、继承、关联(即 关系)、聚集。 动态模型描述系统随时间变化的那些方面,其主要 概念有:状态、子状态和超状态、事件、行为、活动。 功能模型描述系统内部数据值的转换,其主要概念 有:加工、数据存储、数据流、控制流、角色。
OMT方法将开发过程分为4个阶段: 1)分析 基于问题和用户需求的描述,建立现实世界的模型。 2)系统设计 结合问题域的知识和目标系统的体系结构(求解 域),将目标系统分解为子系统。 3)对象设计 基于分析模型和求解域中的体系结构等添加的实现 细节,完成系统设计。 4)实现 将设计转换为特定的编程语言或硬件,同时保持可 追踪性、灵活性和可扩展性。
表9-1 OMT方法的各个阶段及中间结果
阶段 中间结果 问题描述 对象模型用对象图、数据词典表示
分析
动态模型用状态图、全局事件流图表示 功能模型用数据流图、约束表示
系统设计
对象设计
子系统
细化的对象模型 细化的动态模型 细化的功能模型
实现
编程代码
4.OOSE方法 OOSE是Ivar Jacobson在1992年提出的一 种面向对象的开发方法,以“用例”驱动的思 想而著称。 OOSE方法与上述方法有所不同,它涉及到 整个软件生命周期,包括需求分析、设计、实 现和测试4个阶段。OOSE方法中的一个关键概 念就是“用例”。 OOSE方法对以用例驱动进行需求获取、分 析和设计提供了极好的支持。
9.1.3 UML
1.UML的由来 1996年6月和10月分别发布了两个新的统一方法版本, 即UML 0.9和UML 0.91,并将UM重新命名为UML (Unified Modeling Language)。 1996年, UML的开发者得到了来自公众的正面反应, 并倡议成立了UML成员协会,以完善、加强和促进定 义UML的工作。 UML 1.0(1997年1月)及UML 1.1(
1997年11月17日) UML不仅统一了Booch方法、OMT方法、OOSE方法 的表示方法,还做了进一步的发展,最终成为大众接 受的标准建模语言。
2.UML表示法 UML并没有规定具体的软件开发过程,只包 括了概念的语义、表示法和说明,提供了静态、 动态、系统环境及组织结构的模型。UML可被 交互的可视化建模工具所支持,这些工具提供 了代码生成器和报表生成器。UML是为支持大 部分现存的面向对象开发过程而设计的。
图9-3 UML中的视图
3.UML的优点 (1)UML并没有从根本上脱离Booch、 OMT或OOSE方法,而是对这些方法的有批判 的继承。 (2)与Booch、OMT、OOSE等其他方法 相比,统一建模语言具有表达力更强、更清晰 和表达形式一致等优点。
9.1.4 常用的UML视图
1.用例图 用例图主要用来图示化系统的主事件流程,它主要 用来描述客户的需求,即用户希望系统具备的完成一 定功能的动作,可以通俗地将用例理解为软件的功能 模块。
图9-4 一个论坛系统的用例图
2.序列图 序列图主要用于按照交互发生的顺序显示对 象之间的这些交互。
图9-5 一个游戏点卡充值系统的序列图
3.类图 类图展现了一组对象、接口、协作和它们之间的关 系。 表9-2 类之间的关系及其UML表示
类之间的关系 UML表示
泛化
关联 依赖 聚合 组合
图9-6 一个类图的简单例子
4.协作图
图9-7 一个协作图的例子
9.2 面向对象的 分析与设计
9.2.1 面向对象的分析和设计过程 (1)识别系统的用例和角色。 (2)进行系统分析,并抽取类。 (3)系统设计,并设计类及其行为。
9.2.2 面向对象的分析
图9-8 面向对象的分析过程
面向对象的需求分析从概念上又可分为问题分析和应用分析两 个方面。 1.问题分析 问题分析的主要任务是收集并确认用户的需求信息,对实际问 题进行功能分析和过程分析,从中抽象出问题中的基本概念、属 性和操作;然后,用泛化、组成和关联结构描述概念实体间的静 态关系;最后,将概念实体标识为问题域中的对象类,并定义对 象类之间的静态结构和信息连接关系,最终建立关于对象的分析 模型。 2.应用分析 应用分析的主要任务是动态描述系统中对象的合法状态序列, 并用动态模型表达对象的动态行为、对象之间的消息传递和协同 工作的动态信息。对象的动态行为与静态结构密切相关并且受其 约束,静态结构限制了对象状态的取值范围,而动态行为反映了 对象状态的变化序列。
某学校欲开发一个小型图书管理系统,使用计算机实 现对学校图书资料的登记、借出、归还、查询等管理。 该系统有图书管理员和读者两种用户,图书管理员负责
添加、更新和删除系统中的图书资料信息和读者信息, 并登记和查询图书资料的借出情况或归还情况。读者可 以按照作者或者主题检索图书资料信息,并且可以预订 目前借不到的图书资料。系统在Web环境下运行,要求用 户界面友好,响应速度快,具有良好的可扩展性。
1.识别系统的用例和角色 根据问题描述,可以识别出该小型图书管理系统有两类角色: “图书管理员”和“读者”,其相应的用例为: 1)与“图书管理员”有关的用例 (1)管理读者:在系统中增加、删除和修改读者信息。 (2)管理图书:在系统中增加、删除和修改图书信息。 (3)登记借书:在系统中登记读者的借书记录。 (4)登记还书:在系统中登记读者的还书记录。 2)与“读者”有关的用例 (1)预订图书:在系统中登记预订信息。 (2)取消预订:在系统中删除已登记的预订信息。 3)与“图书管理员”和“读者”都有关的用例 (1)用户登录:登录到系统。 (2)图书查询:查询图书信息及图书的借出记录。
图9-9 小型图书管理系统的用例图
2.识别分析类 1)实体类 用于描述必须存储的信息及相关行为,它是对系统 的核心信息建模,通常这些信息需要长久地保存。 图书管理员类(命名为BookManager类)、读者 类(命名为Reader类)、图书资料类(命名为Book 类)、借出情况类(命名为Lend类)、归还情况类 (命名为Return类)、预订情况类(命名为 Reservation类)。 2)边界类 用于描述外部参与者与系统之间的交互,它是对系 统依赖于外部环境的部分进行建模,较好地屏蔽了外 界变化对系统的影响。
图9-10 小型图书管理系统的边界类
3)控制类 控制类用于描述一个用例所具有的事件流控制行为,它本身并 不处理具体的任务,而是调度其他类完成具体的任务。
表9-3 小型图书管理系统中的控制类 用例 管理图书 管理读者 登记借书 相应的控制类 ManageBookControl ManageUserControl LendControl
登记还书
预订图书
ReturnControl
ReservationControl
取消预订
用户登录 图书查询
CancelControl
LoginControl QueryControl
3.定义交互行为 定义交互行为是从需求向设计过渡的一个重要环节, 其关键在于通过描述分析类实例之间的消息传递,将 用例的职责分配到分析类中。
图9-11 “登记借书”的序列图
4.建立分析类图 1)定义属性 对于每个对象,从以下方面考虑并发现其属性: (1)按照一般常识,找出对象的某些属性,如读者的姓名、地址等。 (2)认真研究问题域,找出对象的某些属性,如商品的条形码、读 者的编号等。 (3)根据系统责任的要求,找出对象的某些属性。 (4)
考虑对象需要系统保存和管理的信息,找出对象的相应属性, 如“图书资料”需要保存和管理的信息。 (5)对象为了在服务中实现其功能,需要增设一些属性。 (6)识别对象需要区别的状态,考虑是否需要增加一个属性来区别 这些状态。 (7)确定属性表示整体与部分结构和实例连接。 (8)对于初步发现的属性,检查这些属性是否是系统使用的特征, 是否描述了对象本身的特征,是否可以通过继承得到,是否可以 从其他属性直接导出等,并对这些属性进行整理和筛选。
2)定义泛化关系 可以参考应用领域中已有的一些分类知识,也可以按照自己的常 识从不同角度考虑事物的分类,找出对象类之间的泛化关系。另 外,通过考察系统中每个类的属性和服务,找出类之间的泛化关 系。 查看一个类的属性与服务是否适合这个类的全部对象,如果某些 属性或服务只适合该类的一部分对象,说明应该从这个类中划分 出一部分特殊类,建立泛化关系。 检查是否某些类具有相同的属性和服务,如果把这些相同的属性 和服务提取出来,能否在概念上构成这些类的父类,形成泛化关 系。 为了加强分析模型的可复用性,应该进一步考虑在更高的层次上 运用泛化关系,从而开发一些可复用的构件类。
3)定义聚合、关联等关系 关联存在着多重性,用以描述一个关联的实例中有多少个相互 连接的对象。
图9-12 小型图书管理系统中的类图
9.2.3 面向对象的设计
1.系统设计 系统设计是选择合适的解决方案策略,并将系统划 分成若干子系统,从而建立整个系统的体系结构。 传统的软件设计原则,如模块化、抽象、信息隐藏、 弱耦合、强内聚等,仍然需要遵循。除此之外,还可 以适当考虑以下原则: 1)分层 2)层与层之间互相独立
2.对象设计 对象设计是细化原有的分析对象,确定一些新的对象, 对每一个子系统接口和类进行准确详细的说明。 面向对象设计过程的系统设计阶段包括定义体系结构 策略、识别设计元素、定义数据存储策略和部署子系 统;对象设计阶段包括类设计、组件选择和设计模型 调整。设计过程结束后,形成软件设计说明书。
这里仍以前述的“小型图书管理系统”为例介绍 面向对象的主要设计过程。 1)识别设计元素
表9-4 小型图书管理系统中的设计元素
类型 实 体 类 分析类 图书管理员类 BookManager 读者类Reader …… 边 界 类 控 制 类 LoginForm QueryForm …… LoginControl QueryControl …… 设计元素 设计类BookManager 设计类Reader …… 设计类LoginForm 设计类QueryForm …… 设计类LoginControl 设计类QueryControl ……
2)
确定数据存储策略 目前,常用的数据存储管理有3种方式:数据文件、关 系数据库、面向对象数据库。这3种方式各有优劣,但 以关系数据库最为常用。 在小型图书管理系统中,选择关系数据库ORACLE存 储和管理数据。为了便于应用程序在不同类型的数据 库系统上运行,应将数据存储封装成一个子系统,并 定义与具体产品无关的高层接口。
3)确定部署策略 UML部署图反映了系统中软件和硬件的物理架构, 表示系统运行时的处理节点以及节点中组件的配置。 图9-13显示了小型图书管理系统系统的部署图,用户 在PC机上通过Web浏览器访问某个应用服务器,接着, 应用服务器访问数据库服务器,获得数据,并将结果 反馈给客户端。
图9-13 小型图书管理系统的部署图
4)方法/属性建模 对象设计的主要任务是细化分析和系统设计产生的模型,确 定系统所需的其他对象,其核心活动在于类设计,主要包括方法 建模、属性建模、状态建模和关系建模等。 (1)方法建模:在设计类图上,需要确定方法的可见性、名 称、参数、返回值和构造型。其中,方法也称为操作或成员函数, 方法的可见性是指外部对象对该方法的访问级别。 在UML语言中,方法的可见性有1种级别: 公开的(public):可以被任何其他对象或类的方法调用,用 符号“+”表示。 保护的(protected):只在类层次内部被调用而不能由外部 调用,用符号“#”表示。 私有的(private):只在定义它的类中被调用,用符号“-” 表示。
(2)属性建模:与方法建模类似,类的属性建模也 要进行命名和设置可见性。 (3)状态建模:状态建模是一种动态建模技术,它 主要用于确定系统的行为。在对象设计时,状态建模 一般只发生在通过状态来表示不同行为的类上。在状 态建模中,状态通过对象属性的值来表示。状态的改 变同时是方法调用的结果。
(4)关系建模:在分析阶段可以使用关联关系笼统地表示所有 对象之间的连接,但在实际系统中,对象之间的连接可以有几种 不同的情况,因此在对象设计时需要进一步明确这些关系。 在面向对象软件中,不同对象之间存在4种可能的连接: 全局(Global):某个对象可以在全局范围内直接被其他对象 “引用”。 参数(Parameter):某个对象作为另一个对象的某个操作参 数或者返回值。 局部(Local):某个对象在另一个对象的某个操作中充当临 时变量。 域(Field):某个对象作为另一个对象的数据成员。
9.3 面向对象的 编程
9.3.1 面向对象的编程语言 纯面向对象语言,如Smalltalk和Eiffel等语言 混合型面向对象语言,也就是在
过程语言的基 础上增加面向对象机制,如C++等语言 总体来说,面向对象语言支持面向对象的概念, 如封装、继承、多态、将数据抽象化等。大多 数面向对象语言都提供一个实用的类库。
9.3.2 面向对象程序设计的过程 1.选择编程语言 1)将来能否占主导地位 2)重用性 3)库和开发环境 4)其他因素 2.编码 3.集成 4.测试
9.3.3 面向对象的程序设计风格
良好的面向对象程序设计风格既包括结构化程序设 计风格准则,也包括为适应面向对象所特有的概念(如 继承性)而必须遵循的一些新规则。 1.提高可复用性 (1)提高方法的内聚。 (2)减小方法的规模。 (3)保持方法的一致性,有助于实现代码重用。 (4)把策略与实现分开。 (5)尽量不使用全局信息 (6)利用继承机制 2.提高可扩充性 (1)封装实现策略。 (2)精心确定公有方法。
3.提高健壮性 (1)预防用户的操作错误。 (2)检查参数的合法性。 (3)不要预先确定限定条件。
9.4 面向对象的 软件测试
9.4.1 面向对象测试的分类 1.分析和设计测试 2.编程测试 3.单元测试 4.集成测试 5.系统测试
9.4.2 面向对象测试用例设计原则 (1)对每个测试用例应有特殊的标识,并且 还应与测试的类有明确的联系 (2)测试目的应明确。 (3)应为每个测试用例开发一个测试步骤列 表,列表包含所要测试对象的说明,将要作为 测试结果的消息和操作,测试对象可能发生的 例外情况、外部条件,以及为了正确对软件进 行测试所必须有的外部环境的变化和为了帮助 理解和实现测试所需要的附加信息。
9.4.3 面向对象软件测试的策略 1.基于故障的测试策略 2.基于场景的测试策略 3.类的随机测试策略 4.类层次的分割测试策略 5.由行为模型(状态、活动、顺序和合作图)导出 的测试策略
第9章 结束
谢谢!