第7章 面向对象设计(面向对象软件工程)
1. 软件设计概述
-
面向对象设计的任务:将分析阶段建立的分析模型转变为软件设计模型
-
两种主流设计:
- 以结构化程序设计为基础的结构化软件设计
- 由面向对象方法导出的面向对象软件设计
-
面向对象设计不同于SD:
SD设计:
数据 过程 体系结构 接口面向对象设计:
类/对象的属性/操作--数据、过程 消息设计 --接口 对象间协作 软件架构
1.1 软件设计的概念
- 软件设计的目标:
- 细化解决方案的可视化设计模型
- 确保平滑过渡到程序代码
1.1.1 模块与构件
- 模块(module)
- 一个拥有明确定义输入、输出和特性的程序实体,没有不必要的输入,没有未经模块的转换就变成输出的输入
- 构件(component)
- 可重复使用的软件组件,大多都是在对象的基础上建立的
1.1.2 抽象与细化
- 抽象
- 抽象允许我们通过关注一个实体区别于其它实体的本质特征去管理复杂性。
- 细化
- 将软件的体系结构按自顶向下方式,对各个层次的过程细节和数据细节逐层细化,直到用程序设计语言的语句能够实现为止,从而最后确立整个的体系结构。
- 细化与抽象相反又互补,细化的实质为分解
1.1.3 信息隐藏
- 每个模块的实现细节对于其它模块来说是隐藏的
- 模块内部的数据过程,应该对不需要了解这些数据与过程的模块隐藏起来。只有为了完成软件的总体功能而必须在模块间交换的信息,才允许在模块间进行传递
- 3种不同的设计思想:
-
面向过程的思想
- 各模块的功能可能相互交错或重叠
-
面向功能的思想
- 各模块功能单一
-
面向对象的思想
- 各模块是一个个独立单位,重用性较好
-
1.1.4 软件复用
- 开发人员期望充分利用现有构件,不必一切从头做起
1.2 软件设计的任务
-
把分析阶段产生的分析模型转换为用适当手段表示的软件设计模型
-
不管采用何种软件设计方法,软件设计一般包括数据设计、体系结构设计、接口设计和过程设计
数据设计将分析阶段创建的**信息模型**转变成实现软件所需的**数据结构** 体系结构设计定义软件主要组成部件之间的关系 接口设计描述**软件内部、软件和接口系统之间软件与人之间**是如何通信的(包括数据流和控制流) 过程设计将**软件体系结构的组成部件**转变成对软件组成的**过程性描述** -
传统的设计任务通常包含两个阶段:
- 概要设计
- 详细设计
1.3 模块化设计
-
定义:按照规定的原则把大型软件划分为一个个较小的,相对独立但又相互关联的模块
-
分解和模块独立性是模块化设计的重要指导思想
分解(decomposition) 模块独立性(module independence) 自顶向下(top—down design) 自底向上(bottom—up design)
1.3.1 分解
- 在传统的软件工程中,在分析阶段靠分解来画分层DFD图,在设计阶段常用分解来实现模块化设计
- 在OO软件工程中,靠分解来划分类和对象
1.3.2 模块独立性
- 指软件系统中每个模块只涉及软件要求的具体的子功能, 而和软件系统中其它的模块的接口是简单的
1. 模块独立性模块独立性两个度量准则
- 模块本身的内聚(cohesion)
- 指模块内部各个成分之间的联系,所以也称为块内联系或者模块强度
- 模块之间的耦合(coupling)
- 指一个模块与其他模块之间的联系,也称为块间联系
- 模块独立性比较强的模块应是高内聚低耦合的模块。
内聚强度的划分
- 注意两个图顺序是相反的

- 低内聚
- 偶然性内聚(巧合内聚)
- 模块内各部分之间没有联系,或者即使有联系,这种联系也很松散.是内聚程度最低的模块。
- 逻辑性内聚
- 把在逻辑上相似的功能放在一个模块中,可省去程序中的重复部分,但执行中要从模块外引入用作判断的开关量,会增大块间耦合

- 时间性内聚
- 中内聚
- 过程性内聚
- 当一个模块中包含的一组任务必须按照一特定的次序执行时,就得到过程性模块

- 通信性内聚
-
模块内各成分都使用同一种输入数据,或产生同一个输出数据

-
高内聚
- 顺序性内聚
- 模块中各个组成部分是顺序执行的,通常情况下,上个处理框的输出就是下一个处理框的输入
- 功能性内聚
- 该模块中所有部分都是为了完成一项具体功能而协同工作,紧密联系,不可分割,是块内联系最强的一类模块
耦合强度的划分
-
耦合是对软件内部块间联系的度量,也归纳为7类

-
弱耦合
-
模块1与模块2为同级模块,非直接耦合,相互之间没有信息传递
-
模块3、4都是模块1的下属模块,模块1调用它们时,可通过参数表与它们交换数据。如果交换的都是简单变量,便构成数据耦合(模块1、3之间);如果交换的是数据结构,便构成特征耦合(模块1、4之间)

-
中耦合
- 控制耦合:模块间传递的信息是用作控制信号的开关值或标志量(flag)

- 较强耦合
- 外部耦合:
- 允许一组模块访问同一个全局变量
- 公共耦合
-
允许一组模块访问同一个全局性的数据结构

-
强耦合(内容耦合)
-
如果一个模块可以直接另一模块中的数据,或者允许一个模块直接转移到另一模块中去,则称两个模块之间存在内容耦合
-
耦合越弱,模块的独立性越强
2. 面向对象设计建模
2.1 面向对象设计模型

2.2 面向对象设计任务
- 正如传统设计可以分为概要设计和详细设计两个阶段,OOD的软件设计也可以划分为两个层次:系统架构设计和系统元素设计
-
系统架构设计,主要包括以下6个方面的活动:
* 系统高层结构设计 * 确定设计元素 * 确定任务管理策略:考虑多用户、并发问题 * 实现分布式机制 * 设计数据库存储方案 * 人机界面设计 -
系统元素设计
* 类/对象设计 * 子系统设计 * 包设计
2.3 模式的应用
- 模式的定义:
- 模式是解决一类问题的方法论,也是对通用问题的通用解决方案
- 软件模式的分类:
- 就其抽象的级别而言,软件模式可以分为架构模式、设计模式和习惯用法3种
3. 系统架构设计
3.1 系统高层结构设计
-
常用的架构模式
1. 层级结构(Layers):将系统划分成不同的层次 4层次:应用子系统层、业务专用层、中间件层、系统软件层 2. 模型-视图-控制架构:Model-view-controller (M-V-C) 3. 管道与过滤器架构(Pipes and filters):管道为数据流,过滤器为处理步骤 4. 黑板架构(blackboard)
3.2 确定设计元素
- 映射分析类到设计元素
- 确定子系统:子系统实际上是一种特殊的包
- 定义子系统接口:或将类加上前缀“I”或加上<< interface >>标记来表述子系统接口
3.3 任务管理策略
-
并行处理的解决方案
多处理器方案 操作系统方案 应用程序方案 -
两种实现技术:
- 引进任务管理部件
- 任务管理部件的设计一般遵循如下步骤与策略:
- 识别由事件驱动和时间驱动的任务
- 识别优先任务和关键任务
- 定义各个任务
- 定义任务的工作主要包括:它是什么任务、如何协调工作及如何通信
- 必要时扩充有关任务的类和对象
- 基于进程和线程的控制
-
进程和线程建模:
- 可以用主动类来建模。主动类:指拥有自己的执行线程而且能发起控制活动的类,主动类能与其他主动类并行地执行
-
确定进程的生命周期
-
在进程间分配模型元素
-
- 分别用<< process >>和<< thread >>来标识进程和线程
- 独立的进程间用依赖关系联系
- 若有线程,则用特殊的关联关系---组合关系来表示,因为线程无法独立于进程存在
3.4 分布式应用
- 分布式应用:指应用程序的不同部件被安装在多个通过网络连接的计算机上,系统运行时不同计算机上的部件相互协作,提供应用服务
4. 系统元素设计
4.1 子系统设计
- 将子系统行为分配给子系统元素
- 描述子系统元素
- 说明子系统依赖关系:确保子系统和接口之间没有循环的依赖关系
4.2 分包设计
- 分包的目的:使设计元素更有秩序,呈现出更明显的高内聚、低耦合特征
4.2.1 分包原则:
1. 将边界类打包
2. 将功能相关的类打包
3. 与不同参与者相关的两个类不应在同一包中
4. 可选类和必选类不应在同一包中

4.2.2 描述包之间的依赖关系

4.2.3 包之间的耦合关系
- 一般原则:
- 消除包之间的互相依赖
- 复用价值高的包不要依赖低的包
- 依赖关系不应跨层
- 不要让包直接依赖包含子系统接口的系统元素的包——不要依赖包中的设计元素,而是依赖接口
4.3 类/对象设计
- 描述操作的实现;方法不仅描述操作做什么,还描述操作如何工作
- 操作是黑盒,方法是相应的白盒内容。方法是对操作的实现,由具体的程序设计语言完成。方法说明了实现操作的具体方式
- 即使类本身可以是持久的,但并不是类的所有属性都必须是持久的
- 关系是 “持久”的? 使用域可见性 (field visibility)
- 关联是结构化关系,关联又可以区分为聚集或组合两种类型,聚集是一种特殊的关联,组合程度更强,部分不能独立存在
- 带滚动条的窗口是窗口的一种,所以是泛化关系;滚动条是窗口的一部分,所以是聚集关系


浙公网安备 33010602011771号