? 2008 BUPT TSEG
第十章 面向对象设计修佳鹏 xiujiapeng@bupt.cn
软件工程模型与方法
Models & Methods of Software
Engineering
2? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心本章内容
10.1 面向对象设计综述
10.2 模型的层次化
10.3 面向对象设计原则
10.4 设计用例实现方案
3? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.1 面向对象设计综述
面向对象的设计就是在 OOA模型基础上运用面向对象方法进行系统设计,目标是产生一个符合具体实现条件的面向对象设计( OOD)模型。与实现条件有关的因素有
:图形用户界面、硬件、操作系统、网络
、数据库管理系统、编程语言和可复用的类库等。
OOD的成果是以 UML包图等表示的软件体系结构、以交互图和类图表示的用例实现
、针对复杂对象的状态图和用以描述流程化处理过程的活动图等。
4? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心面向对象的设计过程领 域 概 念 模 型系 统 操 作 契 约用 例 描 述 及 用 例 文 本系 统 顺 序 图分 析 模 型设 计 用 例 实 现 方 案设 计 软 件 体 系 结 构设 计 用 户 界 面交 互 图其 他 ( 状 态 图,活动 图 等 )
软 件 体 系 结 构 图类 图设 计 模 型设 计 过 程
5? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2 模型的层次化
10.2.1 用户界面层
10.2.2 控制器 /处理层
10.2.3 业务 /领域层
10.2.4 持久化层
10.2.5 系统层
6? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心层次化模型
用户界面类实现了系统的主要用户界面元素。
业务 /领域类实现与业务领域相关的概念,源于领域模型 。
控制器/处理类作为完成用例任务的责任承担者,用于协调
、控制其他类共同完成用例规定的功能或行为。
持久类把永久存储、检索、更新和删除对象的能力封装起来
,使底层的存储技术不暴露出来。
系统类为应用提供操作系统相关的功能,通过把特定于操作系统的特性包装起来,使软件与操作系统分离,增加应用的可移植性。
用 户 界 面 类控 制 器 / 处 理 类持 久 类业 务 / 领 域 类系 统 类持 久 存 储
7? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.1 用户界面层
用户界面层指与用户进行交互的部分,包含应用程序中用户界面部分的代码。
系统与用户的用户界面可以以多种形式出现:
图形用户界面 GUI
命令行界面
其他交互界面(语音等)
尽量将用户界面层与系统的业务逻辑分离,专门处理系统与用户的交互。
用户与系统的交互方式发生变化,系统的基本业务逻辑不需改变;系统业务逻辑变化,在交互内容不变的情况下,用户界面不需要进行改变。
8? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.2 控制器 /处理层
当用户通过用户界面使用系统时,用户界面类会产生系统事件传递给控制器类,后者负责该系统事件的处理。
在系统事件的处理过程中,控制器类可能会调用领域类、系统类甚至其他的控制器类。
9? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.3 业务 /领域层
在面向对象分析阶段,已经识别出了问题域中重要的概念,该阶段关注的是概念的本质含义以及属性。
在面向对象设计阶段,将会对这些概念增加操作,并进行必要的修改和调整,使之成为设计模型中业务 /领域层中的类。
这也是为什么说 OOA和 OOD采用一致的表示法,OOA和 OOD之间不存在结构化方法中分析与设计的鸿沟,两者能够紧密衔接。
10? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.4 持久化层
对象持久化:将对象状态永久保存到物理存储介质中。
持久化层提供了存储、检索、更新和删除对象的基础结构。
持久层封装对永久存储介质的访问,但其本身并不是永久存储机制。例如,持久层可能封装了对关系数据库的访问,但本身不是数据库,而是完成持久化功能的类的集合。
11? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心为何引入持久化类
引入持久层的目的在于当数据存储机制或策略发生变化的时候,能减少维护工作。
目前大部分系统都是采用数据库作为存储介质。但数据库肯定会改变,包括:
数据库升级
从一种数据库移动到另一种数据库
数据模式变化,如增加字段、修改字段名称、改变字段类型等
持久层将对数据库的操作类封装起来,提供专门数据管理功能,向业务 /领域对象提供持久化服务,从而使数据库变化对业务领域的影响的范围局部化。
无论持久存储策略如何变化,业务 /领域类都不会受影响,
从而增加了应用程序的可维护性、可扩展性和可移植性。
12? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.5 系统层
系统层提供对操作系统和非面向对象资源的访问。
系统类将操作系统提供的系统调用封装起来,生成系统访问类,例如 Java语言中的文件流类库。上层业务逻辑直接访问系统类
。而不直接访问系统调用。
这样当程序需要在不同操作系统平台上进行移植时,只需要修改少数系统类就可以了。
13? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3 面向对象设计原则
10.3.1单一职责原则 SRP (Single Responsibility Principle)
10.3.2开闭原则 OCP(Open Closed Principle)
10.3.3里氏替换原则 LSP(Liskov Substitution Principle)
10.3.4依赖倒置原则 DIP (Dependency Inversion Principle)
10.3.5接口隔离原则 ISP( Interface Segregation Principle)
10.3.6组合 /聚合复用原则 (Composite/Aggregation Reuse
Principle,CARP)
10.3.7迪米特法则 (Law of Demeter,LoD)
14? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.1单一职责原则 SRP (Single
Responsibility Principle)
就一个类而言,应该仅有一个引起它变化的原因。
职责定义为“变化的原因”。如果你能够想到多于一个的原因去改变一个类,那么这个类就具有多于一个的职责。
类承担了多个职责,等于这些职责都耦合在了一起。一个职责的变化可能会影响这个类完成其他职责的能力。
因此,在构造对象时,应该将对象的不同职责分离至两个或多个类中,确保引起该类变化的原因只有一个,从而提高类的内聚度。
15? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
SRP举例
ComputationalGeometry
Application
Rectangle
+draw()
+getArea()
GUI
GraphicalApplication
ComputationalGeometry
Application
GeometryR
ectangle
+getArea()
GUI
GraphicalApplication
Rectangle
+draw()
16? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.2开闭原则 OCP(Open
Closed Principle)
软件实体 (类、模块、函数等 )应该是 可以扩展,
但是 不可修改 的。
当需求改变时,可以对模块进行扩展,以满足需求的变化。
对模块行为进行扩展时,不必改动客户端模块的源代码或者二进制代码。
符合 OCP原则的程序只通过增加代码来变化,而不是通过更改现有代码来变化。
实现 OCP的关键是使用抽象来识别不同类之间的共性和变化点,利用封装技术对变化点进行封装
。
17? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
OCP实例
Object
18? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.3里氏替换原则 LSP(Liskov
Substitution Principle)
子类应当可以替换父类并出现在父类能够出现的任何地方。
类 A(客户类)调用类 B(服务器类)的操作 A,由于类 C是类 B的子类,实际运行时
,类 C的实例可以替换类 B的实例,完成操作 A的功能,而对于类 A来讲,这种替换是透明的。
19? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.4依赖倒置原则 DIP (Dependency Inversion Principle)
a.高层模块不应该依赖于低层模块。二者都应该依赖于抽象。
b.抽象不应该依赖于细节。细节应该依赖于抽象。
DIP揭示启发式规则是:依赖于抽象,而不是具体的类。也就是说,程序中所有的依赖关系应该终止于抽象类或者接口。
应用程序中所编写的大多数具体类都是不稳定的。通过把它们隐藏在抽象接口的后面,可以隔离它们的不稳定性。
20? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
DIP举例
Policy
Mechanism
Utility
每个较高层次都为它所需要的服务声明一个抽象接口,较低的层次实现了这些抽象接口,每个高层类都通过该抽象接口使用下一层的服务,这样高层就不依赖于低层。低层反而依赖于在高层中声明的抽象服务接口。
21? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
DIP举例
22? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.5接口隔离原则 ISP( Interface Segregation Principle)
采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好 。
如果一个服务器类为多个客户类提供不同的服务
,那么,服务器类应该为每一个客户类创建特定的业务接口,而不要为所有客户类提供统一的业务接口,除非这些客户类请求的服务相同。
23? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.6组合 /聚合复用原则 (Composite/Aggregation Reuse Principle,CARP)
在一个新对象里面使用一些已有对象,使之成为新对象的一部分;新对象通过向已有对象委托( delegate)一部分责任而达到复用已有对象的目的。
面向对象设计中有两种实现复用的手段:一种是继承,一种是组合 /聚合。 CARP原则告诉我们:实现复用时应首先使用组合 /聚合,
其次才考虑继承。
has-a,组合 /聚合
Is-a,继承
24? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心组合 /聚合的优缺点
优点:
新对象访问已有对象的唯一方法是通过已有对象的接口,因此,新对象无法知道已有对象内部实现细节,从而支持了对象封装性。
由于新对象将大部分职责委托给已有对象完成,因此,新对象可以将焦点集中在一个任务上,从而遵循 SRP原则。
组合 /聚合复用可以在运行时刻动态进行,新对象可以动态引用与已有对象接口相同的对象。
作为复用手段可以应用到几乎任何环境中。
缺点:
当新对象已经形成后,需要将另外的已有对象扩充到该新对象中比较困难,只能重新采用组合 /聚合方法生成另外的新对象实现扩充
。
采用组合 /聚合方法实现复用时会产生大量的新对象,给对象管理带来困难。
25? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心继承的优缺点
优点:
子类容易实现。
子类容易扩展。
缺点:
继承复用破坏了封装性。
如果父类发生改变,那么子类的实现也不得不发生改变。
从父类继承而来的实现是静态的,不可能在运行时刻发生改变,没有足够的灵活性。
继承复用只能在一个具有相似语义类层次的上下文环境中使用。
26? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.7迪米特法则 (Law of
Demeter,LoD)
最少知识原则:一个对象应当尽可能少的了解其它对象。
只与你直接的朋友们通信,不要跟“陌生人”说话。
符合下列条件的对象即为朋友:
当前对象本身( this);
以参量形式传入到当前对象方法中的对象;
当前对象的实例变量直接引用的对象;
当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友;
当前对象所创建的对象。
27? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4 设计用例实现方案
10.4.1 类职责分配模式
10.4.2 类职责分配
10.4.3 持久化层设计
10.4.4 创建设计类图
10.4.5 startUp用例
28? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心设计用例实现简介
面向对象分析阶段已经将业务 /领域层中的类基本识别出来,但是其他层的类在进入设计阶段之前都还没有考虑。
设计用例实现方案就是要找出所有这些层中各需要有哪些对象(类)来参与、协同工作,以实现用例的各个场景。
在设计用例实现方案过程中,我们会往业务 /领域层的类中增加属性、操作和方法,实现其从分析类到设计类的转变。
UML协作图是描述对象如何协作以实现用例场景的有效工具。
29? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.1 类职责分配 模式
设计类的来源有两部分。
一部分由领域模型中的概念类转换而来
另一部分则是为实现而新增的一些类,如负责对象持久化的类、负责通信的类。
每一个设计类对应的对象都有自己明确的职责。
对象的职责分为两种类型:
了解型( knowing)职责。细分为三类:对象要了解自己私有的封装数据;了解相关联的对象;了解能够派生或者计算的事物。
行为型( doing)职责。细分为三类:对象自身要能执行一些行为,如创建一个对象或者进行计算;对象要能启动其他对象中的动作;对象要能控制或协调其他对象中的活动。
30? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心面向对象的设计模式
对象的职责通过调用对象的方法来实现。将职责分配给一个对象还是多个对象,是分配给一个方法还是多个方法要受到职责粒度的影响。
面向对象设计最关键的活动是正确地给对象分配职责,这直接关系到设计模型的质量。
模式是面向对象软件的设计经验,是可重用的设计思想,它描述了在特定环境中反复出现的一类设计问题,并提供经过实践检验的解决这类问题的通用模式。
模式定义了一组相互协作的类,包括类的职责和类之间的交互方式。
31? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心模式的组成
模式名称:一个助记名,用一两个词描述模式的问题、解决方案和效果;
问题:描述了何时使用模式。或者说模式的使用问题域;
解决方案:描述了设计的组成部分、组成部分之间的相互关系及各自的职责和协作方式;
效果:描述了模式应用的效果和使用模式应权衡的问题。
32? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心信息专家模式
给对象分配职责的通用原则:
将职责分配给拥有履行职责所必需信息的类 — 即信息专家。换言之,对象处理自己拥有信息的事务。
根据信息专家模式,应该找到拥有履行职责所必须的信息的类,选取类的方法:
如果在设计模型中存在相关的类,先到设计模型中查看;
如果在设计模型中不存在相关的类,则到领域模型中查看,试着应用或扩展领域模型,得出相应的设计类
。
职责的实现需要信息,而信息往往分布在不同的对象中,一个任务可能需要多个对象(信息专家
)协作来完成。
33? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心考试系统实例
在线考试系统中,某个类需要知道 某份考卷选择题 的总得分。那么谁应该负责获取考卷的选择题总得分?
分析:要得到一份考卷的选择题得分,需要知道哪些信息呢?
这份考卷有哪些选择题、以及各选择题的得分。
从单选题或多选题类中获取学生提交的答案。
从考题规格说明中获取该题的标准答案。
34? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心部分领域模型考 卷考 题 考 题 规 格 说 明
1,,*
10,,*
选 择 题 填 空 题 简 答 题 程 序 设 计 题单 选 题 多 选 题
35? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心信息专家
考卷
向设计模型中加入一个软件类,命名为 TestPaper,并且给这个类分配获取选择题总得分的职责,这个职责通过取名为 getScore的方法实现。
考题
向设计模型中增加一个名为 Question(考题)的抽象类,并且给这个类分配获取某道题得分的职责,这个职责通过取名为 getSubScore的抽象方法实现
考试规格说明
向设计模型中增加一个名为 QuestionSpecification(考题规格说明)的类,并且给这个类分配获取该道选择题标准答案的职责,这个职责通过取名为 getAnswer的方法实现。
36? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心类的设计与协作
t h e T e s t P a p e r,
T e s t P a p e r
t h e Q u e s t i o n s
,Q u e s t i o n
1,1 *,t h e Q u e s t i o n = g e t ( s e q u e n c e )
t h e Q u e s t i o n,
Q u e s t i o n
1,2 *,s c o r e = g e t S u b S c o r e ( )
t h e Q u e s t i o n S p e c,
Q u e s t i o n S p e c i f i c a t i o n
1,2,1,a n s w e r 1 = g e t A n s w e r ( )
1,s c o r e = g e t S c o r e ( )
T e s t P a p e r
g e t S c o r e ( )
Q u e s t i o n
g e t S u b S c o r e ( )
Q u e s t i o n S p e c i f i c
a t i o n
g e t A n s w e r ( )
37? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心创建者模式
谁应该负责产生类的实例?
如果符合下面的一个或者多个条件,则可将创建类 A实例的职责分配给类 B(B创建 A)
。
B聚合( aggregate)或包含( contain)对象 A;
B记录( record)对象 A;
B密切使用对象 A;
B拥有创建对象 A所需要的初始化数据( B是创建对象 A的信息专家)。
38? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心创建者模式举例
在线考试系统中,哪个类负责产生考卷生成规则项的实例呢?
寻找哪个类聚合或者包含了许多考卷生成规则项的实例。考虑部分领域模型,因为考卷生成规则聚合了考卷生成规则项对象,因此考卷生成规则类是创建考卷生成规则项实例的很好候选者。
考 试 考 卷 生 成 规 则考 卷 生 成 规 则 项
* 1
1,,*
39? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心控制器模式
哪个非用户接口类应该负责处理一个输入系统事件(一个系统输入事件是由一个外部参与者产生的事件)?
把接收或者处理系统事件的职责分配给这样一个类:
它代表整个系统,称为外观( facade)控制器;
它代表一个发生系统事件的用例场景,这个类通常命名为,<用例名 >控制器”,称为用例控制器或者会话控制器。
在相同的用例场景中使用同一个控制器类处理所有的系统事件;
一次会话是与一个参与者进行交谈的一个实例。
40? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心使用控制器的指导原则
1.当一个系统不具有“太多”的系统事件,或者用户接口不可能将事件消息重定向到其他控制器时,选择外观控制器是合适的。这时,外观控制器相当于一个应用的封面,隔离了用户接口和应用逻辑。
2.如果外观控制器由于职责过多而变得“臃肿”
的时候,应该选择用例控制器。如果选择了用例控制器,那么每一个用例都有一个不同的控制类
,而且只有一个,以便维护用例的状态。用例控制器可以实现有一定执行顺序的系统操作。
3.不论是外观控制器还是用例控制器,它们只是接收系统事件消息,并没有实现系统操作的职责
,系统操作应该委托给领域对象处理。
41? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心学 生选 择 开 始 考 试
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
:,U I,
m a i n W i n d o w
c o n t r o l l e r,
t a k e T e s t C o n t r o l l e r
1,t e s t P a p e r s =
g e t A v a i l a b l e T e s t P a p e r s ( )
系 统 事 件用 户 界 面 层控 制 器 / 处 理 层业 务 / 领 域 层
… …
用 例 控 制 器
42? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.2 类职责分配
寻找对象职责的有效方法之一是绘制交互图。交互图体现了如何为对象分配职责。
当一个对象接收了某条消息,就表明该对象具有处理该条消息的职责。
针对特定场景中各个系统事件单独绘制交互图,用以说明系统接收到该事件后,由哪些对象互相协作、来共同完成对事件的处理,从而抽象出对象以及对象的职责。
43? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心考试系统中的操作操作名称 操作说明
logon(role:string,Id:string,pwd:
string)
登陆系统。操作中的参数分别表示用户名和密码
getAvailableTestPapers
(stuId:string)
罗列出对考生有效的所有考卷
selectTestPaper(courseName:st
ring)
选择一份考卷
logonTestPaper (pwd:string) 登陆一门考试,验证输入的考试密码和考卷要求的密码是否一致
startTest() 开始考试
submitAnswer(questionId:strin
g,answer:string)
提交某道考题的答案
getNextQuestion () 获取下一题
endTest () 结束考试
44? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
logon
,D B F a c a d e
学 生
:,U I,
m a i n L o g o n
:
L o g o n C o n t r o l l e r
2,e l i g i b l e = L o g o n ( i d,p w d )
2,1,t h e S t u d e n t =
g e t ( i d,S t u d e n t )
t h e S t u d e n t,
S t u d e n t
2,2,[ t h e S t u d e n t ! = N U L L ]
r e a l P w d = g e t P w d ( )
2,3,[ t h e S t u d e n t ! = N U L L ]
e l i g i b l e = e q u a l ( p w d,r e a l P w d )
:,U I,
m a i n W i n d o w
3,[ e l i g i b l e = t r u e ]
c r e a t e ( t h e S t u d e n t )
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
3,1,c r e a t e ( t h e S t u d e n t )
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
系 统 事 件
1,c r e a t e ( )
45? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
getAvailableTestPapers
学 生选 择 开 始 考 试
a c t i o n P e r f o r m e
d ( a c t i o n E v e n t )
:,U I,
m a i n W i n d o w
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
1,t e s t P a p e r s =
g e t A v a i l a b l e T e s t P a p e r s ( )
,D B F a c a d e
t h e T e s t P a p e r s
,T e s t P a p e r
1,2,t h e T e s t P a p e r s = g e t s ( s t u I D,T e s t P a p e r )
t h e S t u d e n t,
S t u d e n t
1,1,s t u I D = g e t I D ( )
:,U I,
s h o w T e s t p a p e r
W i n d o w
2,c r e a t e ( t h e T e s t P a p e r s,c o n t r o l l e r )
t h e T e s t P a p e r,
T e s t P a p e r
2,2 *,t e s t N a m e = g e t S u b j e c t N a m e ( )
2,1 *,t h e T e s t P a p e r = g e t ( )
46? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
selectTestPaper
学 生数 据 库考 卷 列 表
:,U I,
E x a m L o g o n
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
:,U I,
s h o w T e s t p a p e r
W i n d o w
3,c r e a t e ( c o n t r o l l e r )
t h e T e s t P a p e r s,
T e s t P a p e r
1,t h e T e s t P a p e r = g e t ( )
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
2,s e t T e s t P a p e r ( t h e T e s t P a p e r )
软 件 工 程
47? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
logonTestPaper
学 生
:,U I,
t e s t P a p e r L o g o n
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
t h e T e s t P a p e r,
T e s t P a p e r
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
1,e l i g i b l e = l o g o n T e s t P a p e r (
p w d )
1,1,r e a l P w d = g e t P w d ( )
1,2,e l i g i b l e = e q u a l ( p w d,r e a l P w d )
:,U I,
t e s t P a p e r
W i n d o w
2,[ e l i g i b l e = t r u e ]
c r e a t e ( c o n t r o l l e r )
48? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
startTest
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
s t a r t T e s t
t h e T e s t P a p e r,
T e s t P a p e r
1,l o a d Q u e s t i o n s ( )
t h e Q u e s t i o n s,
Q u e s t i o n
1,3,c r e a t e ( )
,D B F a c a d e
1,1,t h e R u l e =
g e t ( r u l e I D,R u l e )
t h e R u l e,R u l e
1,2,l o a d R u l e I t e m s ( )
t h e R u l e I t e m s,
R u l e I t e m
1,2,1,t h e R u l e I t e m s = g e t s ( r u l e I D,R u l e I t e m )
1,4,l o a d Q u e s t i o n s
( t h e Q u e s t i o n s )
1,4,2 *,l o a d Q u e s t i o n s
( t h e Q u e s t i o n s,t h e Q u e
s t i o n C a t a l o g )
1,4,1 *,t h e R u l e I t e m = g e t ( )
t h e R u l e I t e m,
R u l e I t e m
t h e Q u e s t i o n C a t a l o g,
Q u e s t i o n C a t a l o g
1,4,2,1 *,q u e s t i o n S p e c =
g e t Q u e s t i o n S p e c ( q u e s t i o n I D )
1,4,2,3 *,a d d ( q u e s t i o n )
t h e Q u e s t i o n,
Q u e s t i o n
1,4,2,2 *,c r e a t e ( q u e s t i o n S p e c )
2,t h e T e s t = g e t ( t e s t I D,T e s t )
t h e T e s t,T e s t
3,d u r a t i o n = g e t D u r a t i o n ( )
4,t h e Q u e s t i o n =
g e t F i r s t Q u e s t i o n ( )
4,1,t h e Q u e s t i o n = g e t ( )
t h e Q u e s t i o n S p e c s,
Q u e s t i o n S p e c i f i c a t i o n
1,4,2,1,1,q u e s t i o n S p e c =
g e t ( q u e s t i o n I D )
1,2,2,c r e a t e ( )
5,s e t T e s t ( t h e T e s t )
49? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
submitAnswer
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
s a v e A n s w e r ( a n s w e r )
t h e Q u e s t i o n,
Q u e s t i o n
1,s e t A n s w e r ( a n s w e r )
50? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
getNextQuestion
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
P r e v i o u s / n e x t
Q u e s t i o n
t h e T e s t P a p e r,
T e s t P a p e r
t h e Q u e s t i o n s,
Q u e s t i o n
1,t h e Q u e s t i o n = g e t Q u e s t i o n ( s e q u e n c e )
1,1,t h e Q u e s t i o n = g e t ( s e q u e n c e )
51? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
endTest
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
e n d T e s t
t h e T e s t P a p e r,
T e s t P a p e r
t h e Q u e s t i o n s
,Q u e s t i o n
1,s c o r e = g e t S c o r e ( )
1,1 *,t h e Q u e s t i o n = g e t ( s e q u e n c e )
t h e Q u e s t i o n,
Q u e s t i o n
1,2 *,,s c o r e = g e t S u b S c o r e ( )
t h e Q u e s t i o n S p e c,
Q u e s t i o n S p e c i f i c a t i o n
1,2,1,a n s w e r 1 = g e t A n s w e r ( )
2,s a v e ( )
2,2 *,s a v e ( )
2,1 *,t h e Q u e s t i o n = g e t ( s e q u e n c e )
,D B F a c a d e
2,2,1,i n s e r t
( t h e Q u e s t i o n,Q u e s t i o n )
,D B F a c a d e
2,3,i n s e r t ( t h e T e s t P a p e r,T e s t P a p e r )
52? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.3 持久化层设计
问题一:谁来负责持久化?
为每一个领域对象设计一个专门负责其持久化的类:
StudentMapper:负责学生信息持久化
TestMapper:负责考试信息持久化
TestPaperMapper:负责考卷信息持久化
以上类中都包含增加、修改、删除和查询操作,所以可以抽象出共同的接口:
IMapper
53? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
IMapper接口设计
,i n t e r f a c e,
I M a p p e r
+ b o o l e a n i n s e r t ( O b j e c t o b j )
+ b o o l e a n d e l e t e ( S t r i n g c o n d i t i o n )
+ b o o l e a n u p d a t e ( O b j e c t o b j )
+ O b j e c t g e t ( S t r i n g c o n d i t i o n )
+ L i s t g e t s ( S t r i n g c o n d i t i o n )
S t u d e n t M a p p e r
T e s t M a p p e r T e s t P a p e r M a p p e r
54? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
DBFacade类设计
问题二:谁来维护领域类和负责其持久化的对应 Mapper类之间的对应关系?
设计类 DBFacade
,i n t e r f a c e,
I M a p p e r
+ b o o l e a n i n s e r t ( O b j e c t o b j )
+ b o o l e a n d e l e t e ( S t r i n g c o n d i t i o n )
+ b o o l e a n u p d a t e ( O b j e c t o b j )
+ O b j e c t g e t ( S t r i n g c o n d i t i o n )
+ L i s t g e t s ( S t r i n g c o n d i t i o n )
S t u d e n t M a p p e r
T e s t M a p p e r T e s t P a p e r M a p p e r
D B F a c a d e
+ b o o l e a n i n s e r t ( O b j e c t o b j,C l a s s )
+ b o o l e a n d e l e t e ( S t r i n g c o n d i t i o n,C l a s s )
+ b o o l e a n u p d a t e ( O b j e c t o b j,C l a s s )
+ O b j e c t g e t ( S t r i n g c o n d i t i o n,C l a s s )
+ L i s t g e t s ( S t r i n g c o n d i t i o n,C l a s s )
- I M a p p e r g e t M a p p e r ( C l a s s )
C l a s s
1
D B C o n n e c t i o n
- m a p p e r C o n t a i n e r
55? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心增加学生持久化过程
1、业务 /领域对象或者控制器 /处理对象实例化 Student类得到对象 theStudent;
2、调用持久化层 DBFacade对象的 insert操作,即向
DBFacade发送 insert消息;
3,insert操作调用 DBFacade对象的 getMapper来获取负责对类 Student的对象进行持久化的对象 theStudentMapper;
4,insert操作调用 theStudentMapper对象的 insert操作,让其将 theStudent对象持久化到存储介质。
,D B F a c a d e
1,t h e S t u d e n t M a p p e r = g e t M a p p e r ( S t u d e n t )
t h e S t u d e n t M a p p e r,
I M a p p e r
2,o k = i n s e r t ( t h e S t u d e n t )
o k = i n s e r t ( t h e S t u d e n t,S t u d e n t )
56? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心查询多个对象过程
,D B F a c a d e
s t u L i s t = g e t s ( c o n d t i o n,S t u d e n t )
1,t h e S t u d e n t M a p p e r = g e t M a p p e r ( S t u d e n t )
t h e S t u d e n t M a p p e r
,I M a p p e r
2,s t u L i s t = g e t s ( c o n d i t i o n )
t h e S t u d e n t,
S t u d e n t
,S t u d e n t
2,1,c r e a t e ( )
2,2,l o a d O b j e c t s ( )
2,2,2 *,a d d ( t h e S t u d e n t )
2,2,1 *,c r e a t e ( )
1、业务 /领域对象或者控制器 /处理对象调用持久化层DBFacade对象的 gets操作,即向 DBFacade发送 gets消息,其中将查询的条件和类作为参数;
2,gets操作调用 DBFacade对象的 getMapper来获取负责对类Student的对象进行持久化的对象 theStudentMapper;
3,gets操作调用 theStudentMapper对象的 gets操作;
4,theStudentMapper对象首先创建一个 Student对象的列表(2.1),调用 gets操作执行查询( 2.2),查到一个记录,即创建一个 theStudent对象( 2.2.1),并将其添加到 Student对象列表当中( 2.2.2)。
57? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.4 创建设计类图
通过类职责分配,我们找出了实现用例的类,以及类的职责。结合分析阶段的领域模型,我们可以得到设计阶段的类图,简称设计类图。
设计类图中主要定义 类、类的属性和操作
,但是不定义实现操作的算法。
58? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心创建设计类图的步骤
第一步:通过扫描所有的交互图以及领域模型中涉及的类,识别参与软件解决方案的类。
第二步:将领域模型中已经识别出来的部分属性添加到类中。
第三步:给类添加操作。通过交互图可以获得每一个类的操作。一般的,发送给类 X的所有消息的集合就是类 X必须定义的大多数操作。
第四步:添加更多的类型信息。包括属性类型、方法参数类型以及返回类型。
第五步:添加关联和导航。
第六步:类成员的细节表示(可选)。如成员的属性可见性,方法体的描述等。
59? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心添加操作的注意事项
1,create创建消息一般被忽略,因为在编程语言中,每个类都有相应的构造函数来实现对象的创建。
2.为了实现封装性,每个对象一般都有简单的存取私有成员的 get和 set方法,这些方法是显然的,为了不干扰设计类图的可读性,不列出 get和 set方法。
3.发送给多对象的消息,处理消息的操作不是多对象中的每一个对象的方法,而是容纳这些对象的容器对象。
60? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心关联和导航
导航( navigability)是关联角色的一个属性
,表示从一个源对象沿着关联导航方向可以单向地到达一个目标类。在面向对象编程语言中,如果类 A要导航到类 B,则在类
A中将创建一个类 B的实例属性。
定义 A到 B带导航修饰关联的常见情况有以下几种:
A发送一个消息到 B;
A创建一个 B的实例;
A需要维护到 B的一个连接。
61? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心用户界面层设计类图
62? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心控制器 /处理层设计类图
63? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心业务 /领域层设计类图控制器 /处理层业务 /领域层持久化层
64? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心持久化层设计类图
65? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.5 startUp用例
大多数系统在启动过程中都要做一些系统初始化操作,所以可以设置一个 startUp用例,来完成相关初始化工作。
一般最后再进行 startUp用例的设计,以保证其包含所有初始化活动。
startUp用例的实现通过创建领域对象来实现。
初始化领域对象的选择原则是:选择领域对象的容器,或者聚集层次结构的根或临近根的类作为初始化领域对象的类。
在在线考试系统中,假如在系统初始化过程中将
“考题规格说明”信息读取到系统内存中,则在系统启动时,可以在 main函数中将 Rule对象实例化,并调用其方法将相关信息读入系统内存。
第十章 面向对象设计修佳鹏 xiujiapeng@bupt.cn
软件工程模型与方法
Models & Methods of Software
Engineering
2? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心本章内容
10.1 面向对象设计综述
10.2 模型的层次化
10.3 面向对象设计原则
10.4 设计用例实现方案
3? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.1 面向对象设计综述
面向对象的设计就是在 OOA模型基础上运用面向对象方法进行系统设计,目标是产生一个符合具体实现条件的面向对象设计( OOD)模型。与实现条件有关的因素有
:图形用户界面、硬件、操作系统、网络
、数据库管理系统、编程语言和可复用的类库等。
OOD的成果是以 UML包图等表示的软件体系结构、以交互图和类图表示的用例实现
、针对复杂对象的状态图和用以描述流程化处理过程的活动图等。
4? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心面向对象的设计过程领 域 概 念 模 型系 统 操 作 契 约用 例 描 述 及 用 例 文 本系 统 顺 序 图分 析 模 型设 计 用 例 实 现 方 案设 计 软 件 体 系 结 构设 计 用 户 界 面交 互 图其 他 ( 状 态 图,活动 图 等 )
软 件 体 系 结 构 图类 图设 计 模 型设 计 过 程
5? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2 模型的层次化
10.2.1 用户界面层
10.2.2 控制器 /处理层
10.2.3 业务 /领域层
10.2.4 持久化层
10.2.5 系统层
6? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心层次化模型
用户界面类实现了系统的主要用户界面元素。
业务 /领域类实现与业务领域相关的概念,源于领域模型 。
控制器/处理类作为完成用例任务的责任承担者,用于协调
、控制其他类共同完成用例规定的功能或行为。
持久类把永久存储、检索、更新和删除对象的能力封装起来
,使底层的存储技术不暴露出来。
系统类为应用提供操作系统相关的功能,通过把特定于操作系统的特性包装起来,使软件与操作系统分离,增加应用的可移植性。
用 户 界 面 类控 制 器 / 处 理 类持 久 类业 务 / 领 域 类系 统 类持 久 存 储
7? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.1 用户界面层
用户界面层指与用户进行交互的部分,包含应用程序中用户界面部分的代码。
系统与用户的用户界面可以以多种形式出现:
图形用户界面 GUI
命令行界面
其他交互界面(语音等)
尽量将用户界面层与系统的业务逻辑分离,专门处理系统与用户的交互。
用户与系统的交互方式发生变化,系统的基本业务逻辑不需改变;系统业务逻辑变化,在交互内容不变的情况下,用户界面不需要进行改变。
8? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.2 控制器 /处理层
当用户通过用户界面使用系统时,用户界面类会产生系统事件传递给控制器类,后者负责该系统事件的处理。
在系统事件的处理过程中,控制器类可能会调用领域类、系统类甚至其他的控制器类。
9? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.3 业务 /领域层
在面向对象分析阶段,已经识别出了问题域中重要的概念,该阶段关注的是概念的本质含义以及属性。
在面向对象设计阶段,将会对这些概念增加操作,并进行必要的修改和调整,使之成为设计模型中业务 /领域层中的类。
这也是为什么说 OOA和 OOD采用一致的表示法,OOA和 OOD之间不存在结构化方法中分析与设计的鸿沟,两者能够紧密衔接。
10? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.4 持久化层
对象持久化:将对象状态永久保存到物理存储介质中。
持久化层提供了存储、检索、更新和删除对象的基础结构。
持久层封装对永久存储介质的访问,但其本身并不是永久存储机制。例如,持久层可能封装了对关系数据库的访问,但本身不是数据库,而是完成持久化功能的类的集合。
11? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心为何引入持久化类
引入持久层的目的在于当数据存储机制或策略发生变化的时候,能减少维护工作。
目前大部分系统都是采用数据库作为存储介质。但数据库肯定会改变,包括:
数据库升级
从一种数据库移动到另一种数据库
数据模式变化,如增加字段、修改字段名称、改变字段类型等
持久层将对数据库的操作类封装起来,提供专门数据管理功能,向业务 /领域对象提供持久化服务,从而使数据库变化对业务领域的影响的范围局部化。
无论持久存储策略如何变化,业务 /领域类都不会受影响,
从而增加了应用程序的可维护性、可扩展性和可移植性。
12? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.2.5 系统层
系统层提供对操作系统和非面向对象资源的访问。
系统类将操作系统提供的系统调用封装起来,生成系统访问类,例如 Java语言中的文件流类库。上层业务逻辑直接访问系统类
。而不直接访问系统调用。
这样当程序需要在不同操作系统平台上进行移植时,只需要修改少数系统类就可以了。
13? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3 面向对象设计原则
10.3.1单一职责原则 SRP (Single Responsibility Principle)
10.3.2开闭原则 OCP(Open Closed Principle)
10.3.3里氏替换原则 LSP(Liskov Substitution Principle)
10.3.4依赖倒置原则 DIP (Dependency Inversion Principle)
10.3.5接口隔离原则 ISP( Interface Segregation Principle)
10.3.6组合 /聚合复用原则 (Composite/Aggregation Reuse
Principle,CARP)
10.3.7迪米特法则 (Law of Demeter,LoD)
14? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.1单一职责原则 SRP (Single
Responsibility Principle)
就一个类而言,应该仅有一个引起它变化的原因。
职责定义为“变化的原因”。如果你能够想到多于一个的原因去改变一个类,那么这个类就具有多于一个的职责。
类承担了多个职责,等于这些职责都耦合在了一起。一个职责的变化可能会影响这个类完成其他职责的能力。
因此,在构造对象时,应该将对象的不同职责分离至两个或多个类中,确保引起该类变化的原因只有一个,从而提高类的内聚度。
15? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
SRP举例
ComputationalGeometry
Application
Rectangle
+draw()
+getArea()
GUI
GraphicalApplication
ComputationalGeometry
Application
GeometryR
ectangle
+getArea()
GUI
GraphicalApplication
Rectangle
+draw()
16? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.2开闭原则 OCP(Open
Closed Principle)
软件实体 (类、模块、函数等 )应该是 可以扩展,
但是 不可修改 的。
当需求改变时,可以对模块进行扩展,以满足需求的变化。
对模块行为进行扩展时,不必改动客户端模块的源代码或者二进制代码。
符合 OCP原则的程序只通过增加代码来变化,而不是通过更改现有代码来变化。
实现 OCP的关键是使用抽象来识别不同类之间的共性和变化点,利用封装技术对变化点进行封装
。
17? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
OCP实例
Object
18? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.3里氏替换原则 LSP(Liskov
Substitution Principle)
子类应当可以替换父类并出现在父类能够出现的任何地方。
类 A(客户类)调用类 B(服务器类)的操作 A,由于类 C是类 B的子类,实际运行时
,类 C的实例可以替换类 B的实例,完成操作 A的功能,而对于类 A来讲,这种替换是透明的。
19? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.4依赖倒置原则 DIP (Dependency Inversion Principle)
a.高层模块不应该依赖于低层模块。二者都应该依赖于抽象。
b.抽象不应该依赖于细节。细节应该依赖于抽象。
DIP揭示启发式规则是:依赖于抽象,而不是具体的类。也就是说,程序中所有的依赖关系应该终止于抽象类或者接口。
应用程序中所编写的大多数具体类都是不稳定的。通过把它们隐藏在抽象接口的后面,可以隔离它们的不稳定性。
20? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
DIP举例
Policy
Mechanism
Utility
每个较高层次都为它所需要的服务声明一个抽象接口,较低的层次实现了这些抽象接口,每个高层类都通过该抽象接口使用下一层的服务,这样高层就不依赖于低层。低层反而依赖于在高层中声明的抽象服务接口。
21? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
DIP举例
22? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.5接口隔离原则 ISP( Interface Segregation Principle)
采用多个与特定客户类有关的接口比采用一个通用的涵盖多个业务方法的接口要好 。
如果一个服务器类为多个客户类提供不同的服务
,那么,服务器类应该为每一个客户类创建特定的业务接口,而不要为所有客户类提供统一的业务接口,除非这些客户类请求的服务相同。
23? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.6组合 /聚合复用原则 (Composite/Aggregation Reuse Principle,CARP)
在一个新对象里面使用一些已有对象,使之成为新对象的一部分;新对象通过向已有对象委托( delegate)一部分责任而达到复用已有对象的目的。
面向对象设计中有两种实现复用的手段:一种是继承,一种是组合 /聚合。 CARP原则告诉我们:实现复用时应首先使用组合 /聚合,
其次才考虑继承。
has-a,组合 /聚合
Is-a,继承
24? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心组合 /聚合的优缺点
优点:
新对象访问已有对象的唯一方法是通过已有对象的接口,因此,新对象无法知道已有对象内部实现细节,从而支持了对象封装性。
由于新对象将大部分职责委托给已有对象完成,因此,新对象可以将焦点集中在一个任务上,从而遵循 SRP原则。
组合 /聚合复用可以在运行时刻动态进行,新对象可以动态引用与已有对象接口相同的对象。
作为复用手段可以应用到几乎任何环境中。
缺点:
当新对象已经形成后,需要将另外的已有对象扩充到该新对象中比较困难,只能重新采用组合 /聚合方法生成另外的新对象实现扩充
。
采用组合 /聚合方法实现复用时会产生大量的新对象,给对象管理带来困难。
25? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心继承的优缺点
优点:
子类容易实现。
子类容易扩展。
缺点:
继承复用破坏了封装性。
如果父类发生改变,那么子类的实现也不得不发生改变。
从父类继承而来的实现是静态的,不可能在运行时刻发生改变,没有足够的灵活性。
继承复用只能在一个具有相似语义类层次的上下文环境中使用。
26? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.3.7迪米特法则 (Law of
Demeter,LoD)
最少知识原则:一个对象应当尽可能少的了解其它对象。
只与你直接的朋友们通信,不要跟“陌生人”说话。
符合下列条件的对象即为朋友:
当前对象本身( this);
以参量形式传入到当前对象方法中的对象;
当前对象的实例变量直接引用的对象;
当前对象的实例变量如果是一个聚集,那么聚集中的元素也都是朋友;
当前对象所创建的对象。
27? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4 设计用例实现方案
10.4.1 类职责分配模式
10.4.2 类职责分配
10.4.3 持久化层设计
10.4.4 创建设计类图
10.4.5 startUp用例
28? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心设计用例实现简介
面向对象分析阶段已经将业务 /领域层中的类基本识别出来,但是其他层的类在进入设计阶段之前都还没有考虑。
设计用例实现方案就是要找出所有这些层中各需要有哪些对象(类)来参与、协同工作,以实现用例的各个场景。
在设计用例实现方案过程中,我们会往业务 /领域层的类中增加属性、操作和方法,实现其从分析类到设计类的转变。
UML协作图是描述对象如何协作以实现用例场景的有效工具。
29? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.1 类职责分配 模式
设计类的来源有两部分。
一部分由领域模型中的概念类转换而来
另一部分则是为实现而新增的一些类,如负责对象持久化的类、负责通信的类。
每一个设计类对应的对象都有自己明确的职责。
对象的职责分为两种类型:
了解型( knowing)职责。细分为三类:对象要了解自己私有的封装数据;了解相关联的对象;了解能够派生或者计算的事物。
行为型( doing)职责。细分为三类:对象自身要能执行一些行为,如创建一个对象或者进行计算;对象要能启动其他对象中的动作;对象要能控制或协调其他对象中的活动。
30? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心面向对象的设计模式
对象的职责通过调用对象的方法来实现。将职责分配给一个对象还是多个对象,是分配给一个方法还是多个方法要受到职责粒度的影响。
面向对象设计最关键的活动是正确地给对象分配职责,这直接关系到设计模型的质量。
模式是面向对象软件的设计经验,是可重用的设计思想,它描述了在特定环境中反复出现的一类设计问题,并提供经过实践检验的解决这类问题的通用模式。
模式定义了一组相互协作的类,包括类的职责和类之间的交互方式。
31? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心模式的组成
模式名称:一个助记名,用一两个词描述模式的问题、解决方案和效果;
问题:描述了何时使用模式。或者说模式的使用问题域;
解决方案:描述了设计的组成部分、组成部分之间的相互关系及各自的职责和协作方式;
效果:描述了模式应用的效果和使用模式应权衡的问题。
32? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心信息专家模式
给对象分配职责的通用原则:
将职责分配给拥有履行职责所必需信息的类 — 即信息专家。换言之,对象处理自己拥有信息的事务。
根据信息专家模式,应该找到拥有履行职责所必须的信息的类,选取类的方法:
如果在设计模型中存在相关的类,先到设计模型中查看;
如果在设计模型中不存在相关的类,则到领域模型中查看,试着应用或扩展领域模型,得出相应的设计类
。
职责的实现需要信息,而信息往往分布在不同的对象中,一个任务可能需要多个对象(信息专家
)协作来完成。
33? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心考试系统实例
在线考试系统中,某个类需要知道 某份考卷选择题 的总得分。那么谁应该负责获取考卷的选择题总得分?
分析:要得到一份考卷的选择题得分,需要知道哪些信息呢?
这份考卷有哪些选择题、以及各选择题的得分。
从单选题或多选题类中获取学生提交的答案。
从考题规格说明中获取该题的标准答案。
34? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心部分领域模型考 卷考 题 考 题 规 格 说 明
1,,*
10,,*
选 择 题 填 空 题 简 答 题 程 序 设 计 题单 选 题 多 选 题
35? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心信息专家
考卷
向设计模型中加入一个软件类,命名为 TestPaper,并且给这个类分配获取选择题总得分的职责,这个职责通过取名为 getScore的方法实现。
考题
向设计模型中增加一个名为 Question(考题)的抽象类,并且给这个类分配获取某道题得分的职责,这个职责通过取名为 getSubScore的抽象方法实现
考试规格说明
向设计模型中增加一个名为 QuestionSpecification(考题规格说明)的类,并且给这个类分配获取该道选择题标准答案的职责,这个职责通过取名为 getAnswer的方法实现。
36? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心类的设计与协作
t h e T e s t P a p e r,
T e s t P a p e r
t h e Q u e s t i o n s
,Q u e s t i o n
1,1 *,t h e Q u e s t i o n = g e t ( s e q u e n c e )
t h e Q u e s t i o n,
Q u e s t i o n
1,2 *,s c o r e = g e t S u b S c o r e ( )
t h e Q u e s t i o n S p e c,
Q u e s t i o n S p e c i f i c a t i o n
1,2,1,a n s w e r 1 = g e t A n s w e r ( )
1,s c o r e = g e t S c o r e ( )
T e s t P a p e r
g e t S c o r e ( )
Q u e s t i o n
g e t S u b S c o r e ( )
Q u e s t i o n S p e c i f i c
a t i o n
g e t A n s w e r ( )
37? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心创建者模式
谁应该负责产生类的实例?
如果符合下面的一个或者多个条件,则可将创建类 A实例的职责分配给类 B(B创建 A)
。
B聚合( aggregate)或包含( contain)对象 A;
B记录( record)对象 A;
B密切使用对象 A;
B拥有创建对象 A所需要的初始化数据( B是创建对象 A的信息专家)。
38? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心创建者模式举例
在线考试系统中,哪个类负责产生考卷生成规则项的实例呢?
寻找哪个类聚合或者包含了许多考卷生成规则项的实例。考虑部分领域模型,因为考卷生成规则聚合了考卷生成规则项对象,因此考卷生成规则类是创建考卷生成规则项实例的很好候选者。
考 试 考 卷 生 成 规 则考 卷 生 成 规 则 项
* 1
1,,*
39? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心控制器模式
哪个非用户接口类应该负责处理一个输入系统事件(一个系统输入事件是由一个外部参与者产生的事件)?
把接收或者处理系统事件的职责分配给这样一个类:
它代表整个系统,称为外观( facade)控制器;
它代表一个发生系统事件的用例场景,这个类通常命名为,<用例名 >控制器”,称为用例控制器或者会话控制器。
在相同的用例场景中使用同一个控制器类处理所有的系统事件;
一次会话是与一个参与者进行交谈的一个实例。
40? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心使用控制器的指导原则
1.当一个系统不具有“太多”的系统事件,或者用户接口不可能将事件消息重定向到其他控制器时,选择外观控制器是合适的。这时,外观控制器相当于一个应用的封面,隔离了用户接口和应用逻辑。
2.如果外观控制器由于职责过多而变得“臃肿”
的时候,应该选择用例控制器。如果选择了用例控制器,那么每一个用例都有一个不同的控制类
,而且只有一个,以便维护用例的状态。用例控制器可以实现有一定执行顺序的系统操作。
3.不论是外观控制器还是用例控制器,它们只是接收系统事件消息,并没有实现系统操作的职责
,系统操作应该委托给领域对象处理。
41? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心学 生选 择 开 始 考 试
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
:,U I,
m a i n W i n d o w
c o n t r o l l e r,
t a k e T e s t C o n t r o l l e r
1,t e s t P a p e r s =
g e t A v a i l a b l e T e s t P a p e r s ( )
系 统 事 件用 户 界 面 层控 制 器 / 处 理 层业 务 / 领 域 层
… …
用 例 控 制 器
42? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.2 类职责分配
寻找对象职责的有效方法之一是绘制交互图。交互图体现了如何为对象分配职责。
当一个对象接收了某条消息,就表明该对象具有处理该条消息的职责。
针对特定场景中各个系统事件单独绘制交互图,用以说明系统接收到该事件后,由哪些对象互相协作、来共同完成对事件的处理,从而抽象出对象以及对象的职责。
43? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心考试系统中的操作操作名称 操作说明
logon(role:string,Id:string,pwd:
string)
登陆系统。操作中的参数分别表示用户名和密码
getAvailableTestPapers
(stuId:string)
罗列出对考生有效的所有考卷
selectTestPaper(courseName:st
ring)
选择一份考卷
logonTestPaper (pwd:string) 登陆一门考试,验证输入的考试密码和考卷要求的密码是否一致
startTest() 开始考试
submitAnswer(questionId:strin
g,answer:string)
提交某道考题的答案
getNextQuestion () 获取下一题
endTest () 结束考试
44? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
logon
,D B F a c a d e
学 生
:,U I,
m a i n L o g o n
:
L o g o n C o n t r o l l e r
2,e l i g i b l e = L o g o n ( i d,p w d )
2,1,t h e S t u d e n t =
g e t ( i d,S t u d e n t )
t h e S t u d e n t,
S t u d e n t
2,2,[ t h e S t u d e n t ! = N U L L ]
r e a l P w d = g e t P w d ( )
2,3,[ t h e S t u d e n t ! = N U L L ]
e l i g i b l e = e q u a l ( p w d,r e a l P w d )
:,U I,
m a i n W i n d o w
3,[ e l i g i b l e = t r u e ]
c r e a t e ( t h e S t u d e n t )
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
3,1,c r e a t e ( t h e S t u d e n t )
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
系 统 事 件
1,c r e a t e ( )
45? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
getAvailableTestPapers
学 生选 择 开 始 考 试
a c t i o n P e r f o r m e
d ( a c t i o n E v e n t )
:,U I,
m a i n W i n d o w
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
1,t e s t P a p e r s =
g e t A v a i l a b l e T e s t P a p e r s ( )
,D B F a c a d e
t h e T e s t P a p e r s
,T e s t P a p e r
1,2,t h e T e s t P a p e r s = g e t s ( s t u I D,T e s t P a p e r )
t h e S t u d e n t,
S t u d e n t
1,1,s t u I D = g e t I D ( )
:,U I,
s h o w T e s t p a p e r
W i n d o w
2,c r e a t e ( t h e T e s t P a p e r s,c o n t r o l l e r )
t h e T e s t P a p e r,
T e s t P a p e r
2,2 *,t e s t N a m e = g e t S u b j e c t N a m e ( )
2,1 *,t h e T e s t P a p e r = g e t ( )
46? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
selectTestPaper
学 生数 据 库考 卷 列 表
:,U I,
E x a m L o g o n
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
:,U I,
s h o w T e s t p a p e r
W i n d o w
3,c r e a t e ( c o n t r o l l e r )
t h e T e s t P a p e r s,
T e s t P a p e r
1,t h e T e s t P a p e r = g e t ( )
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
2,s e t T e s t P a p e r ( t h e T e s t P a p e r )
软 件 工 程
47? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
logonTestPaper
学 生
:,U I,
t e s t P a p e r L o g o n
a c t i o n P e r f o r m e d
( a c t i o n E v e n t )
t h e T e s t P a p e r,
T e s t P a p e r
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
1,e l i g i b l e = l o g o n T e s t P a p e r (
p w d )
1,1,r e a l P w d = g e t P w d ( )
1,2,e l i g i b l e = e q u a l ( p w d,r e a l P w d )
:,U I,
t e s t P a p e r
W i n d o w
2,[ e l i g i b l e = t r u e ]
c r e a t e ( c o n t r o l l e r )
48? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
startTest
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
s t a r t T e s t
t h e T e s t P a p e r,
T e s t P a p e r
1,l o a d Q u e s t i o n s ( )
t h e Q u e s t i o n s,
Q u e s t i o n
1,3,c r e a t e ( )
,D B F a c a d e
1,1,t h e R u l e =
g e t ( r u l e I D,R u l e )
t h e R u l e,R u l e
1,2,l o a d R u l e I t e m s ( )
t h e R u l e I t e m s,
R u l e I t e m
1,2,1,t h e R u l e I t e m s = g e t s ( r u l e I D,R u l e I t e m )
1,4,l o a d Q u e s t i o n s
( t h e Q u e s t i o n s )
1,4,2 *,l o a d Q u e s t i o n s
( t h e Q u e s t i o n s,t h e Q u e
s t i o n C a t a l o g )
1,4,1 *,t h e R u l e I t e m = g e t ( )
t h e R u l e I t e m,
R u l e I t e m
t h e Q u e s t i o n C a t a l o g,
Q u e s t i o n C a t a l o g
1,4,2,1 *,q u e s t i o n S p e c =
g e t Q u e s t i o n S p e c ( q u e s t i o n I D )
1,4,2,3 *,a d d ( q u e s t i o n )
t h e Q u e s t i o n,
Q u e s t i o n
1,4,2,2 *,c r e a t e ( q u e s t i o n S p e c )
2,t h e T e s t = g e t ( t e s t I D,T e s t )
t h e T e s t,T e s t
3,d u r a t i o n = g e t D u r a t i o n ( )
4,t h e Q u e s t i o n =
g e t F i r s t Q u e s t i o n ( )
4,1,t h e Q u e s t i o n = g e t ( )
t h e Q u e s t i o n S p e c s,
Q u e s t i o n S p e c i f i c a t i o n
1,4,2,1,1,q u e s t i o n S p e c =
g e t ( q u e s t i o n I D )
1,2,2,c r e a t e ( )
5,s e t T e s t ( t h e T e s t )
49? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
submitAnswer
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
s a v e A n s w e r ( a n s w e r )
t h e Q u e s t i o n,
Q u e s t i o n
1,s e t A n s w e r ( a n s w e r )
50? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
getNextQuestion
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
P r e v i o u s / n e x t
Q u e s t i o n
t h e T e s t P a p e r,
T e s t P a p e r
t h e Q u e s t i o n s,
Q u e s t i o n
1,t h e Q u e s t i o n = g e t Q u e s t i o n ( s e q u e n c e )
1,1,t h e Q u e s t i o n = g e t ( s e q u e n c e )
51? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
endTest
:,U I,
t e s t P a p e r
W i n d o w
学 生
c o n t r o l l e r,
T a k e T e s t C o n t r o l l e r
e n d T e s t
t h e T e s t P a p e r,
T e s t P a p e r
t h e Q u e s t i o n s
,Q u e s t i o n
1,s c o r e = g e t S c o r e ( )
1,1 *,t h e Q u e s t i o n = g e t ( s e q u e n c e )
t h e Q u e s t i o n,
Q u e s t i o n
1,2 *,,s c o r e = g e t S u b S c o r e ( )
t h e Q u e s t i o n S p e c,
Q u e s t i o n S p e c i f i c a t i o n
1,2,1,a n s w e r 1 = g e t A n s w e r ( )
2,s a v e ( )
2,2 *,s a v e ( )
2,1 *,t h e Q u e s t i o n = g e t ( s e q u e n c e )
,D B F a c a d e
2,2,1,i n s e r t
( t h e Q u e s t i o n,Q u e s t i o n )
,D B F a c a d e
2,3,i n s e r t ( t h e T e s t P a p e r,T e s t P a p e r )
52? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.3 持久化层设计
问题一:谁来负责持久化?
为每一个领域对象设计一个专门负责其持久化的类:
StudentMapper:负责学生信息持久化
TestMapper:负责考试信息持久化
TestPaperMapper:负责考卷信息持久化
以上类中都包含增加、修改、删除和查询操作,所以可以抽象出共同的接口:
IMapper
53? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
IMapper接口设计
,i n t e r f a c e,
I M a p p e r
+ b o o l e a n i n s e r t ( O b j e c t o b j )
+ b o o l e a n d e l e t e ( S t r i n g c o n d i t i o n )
+ b o o l e a n u p d a t e ( O b j e c t o b j )
+ O b j e c t g e t ( S t r i n g c o n d i t i o n )
+ L i s t g e t s ( S t r i n g c o n d i t i o n )
S t u d e n t M a p p e r
T e s t M a p p e r T e s t P a p e r M a p p e r
54? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
DBFacade类设计
问题二:谁来维护领域类和负责其持久化的对应 Mapper类之间的对应关系?
设计类 DBFacade
,i n t e r f a c e,
I M a p p e r
+ b o o l e a n i n s e r t ( O b j e c t o b j )
+ b o o l e a n d e l e t e ( S t r i n g c o n d i t i o n )
+ b o o l e a n u p d a t e ( O b j e c t o b j )
+ O b j e c t g e t ( S t r i n g c o n d i t i o n )
+ L i s t g e t s ( S t r i n g c o n d i t i o n )
S t u d e n t M a p p e r
T e s t M a p p e r T e s t P a p e r M a p p e r
D B F a c a d e
+ b o o l e a n i n s e r t ( O b j e c t o b j,C l a s s )
+ b o o l e a n d e l e t e ( S t r i n g c o n d i t i o n,C l a s s )
+ b o o l e a n u p d a t e ( O b j e c t o b j,C l a s s )
+ O b j e c t g e t ( S t r i n g c o n d i t i o n,C l a s s )
+ L i s t g e t s ( S t r i n g c o n d i t i o n,C l a s s )
- I M a p p e r g e t M a p p e r ( C l a s s )
C l a s s
1
D B C o n n e c t i o n
- m a p p e r C o n t a i n e r
55? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心增加学生持久化过程
1、业务 /领域对象或者控制器 /处理对象实例化 Student类得到对象 theStudent;
2、调用持久化层 DBFacade对象的 insert操作,即向
DBFacade发送 insert消息;
3,insert操作调用 DBFacade对象的 getMapper来获取负责对类 Student的对象进行持久化的对象 theStudentMapper;
4,insert操作调用 theStudentMapper对象的 insert操作,让其将 theStudent对象持久化到存储介质。
,D B F a c a d e
1,t h e S t u d e n t M a p p e r = g e t M a p p e r ( S t u d e n t )
t h e S t u d e n t M a p p e r,
I M a p p e r
2,o k = i n s e r t ( t h e S t u d e n t )
o k = i n s e r t ( t h e S t u d e n t,S t u d e n t )
56? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心查询多个对象过程
,D B F a c a d e
s t u L i s t = g e t s ( c o n d t i o n,S t u d e n t )
1,t h e S t u d e n t M a p p e r = g e t M a p p e r ( S t u d e n t )
t h e S t u d e n t M a p p e r
,I M a p p e r
2,s t u L i s t = g e t s ( c o n d i t i o n )
t h e S t u d e n t,
S t u d e n t
,S t u d e n t
2,1,c r e a t e ( )
2,2,l o a d O b j e c t s ( )
2,2,2 *,a d d ( t h e S t u d e n t )
2,2,1 *,c r e a t e ( )
1、业务 /领域对象或者控制器 /处理对象调用持久化层DBFacade对象的 gets操作,即向 DBFacade发送 gets消息,其中将查询的条件和类作为参数;
2,gets操作调用 DBFacade对象的 getMapper来获取负责对类Student的对象进行持久化的对象 theStudentMapper;
3,gets操作调用 theStudentMapper对象的 gets操作;
4,theStudentMapper对象首先创建一个 Student对象的列表(2.1),调用 gets操作执行查询( 2.2),查到一个记录,即创建一个 theStudent对象( 2.2.1),并将其添加到 Student对象列表当中( 2.2.2)。
57? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.4 创建设计类图
通过类职责分配,我们找出了实现用例的类,以及类的职责。结合分析阶段的领域模型,我们可以得到设计阶段的类图,简称设计类图。
设计类图中主要定义 类、类的属性和操作
,但是不定义实现操作的算法。
58? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心创建设计类图的步骤
第一步:通过扫描所有的交互图以及领域模型中涉及的类,识别参与软件解决方案的类。
第二步:将领域模型中已经识别出来的部分属性添加到类中。
第三步:给类添加操作。通过交互图可以获得每一个类的操作。一般的,发送给类 X的所有消息的集合就是类 X必须定义的大多数操作。
第四步:添加更多的类型信息。包括属性类型、方法参数类型以及返回类型。
第五步:添加关联和导航。
第六步:类成员的细节表示(可选)。如成员的属性可见性,方法体的描述等。
59? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心添加操作的注意事项
1,create创建消息一般被忽略,因为在编程语言中,每个类都有相应的构造函数来实现对象的创建。
2.为了实现封装性,每个对象一般都有简单的存取私有成员的 get和 set方法,这些方法是显然的,为了不干扰设计类图的可读性,不列出 get和 set方法。
3.发送给多对象的消息,处理消息的操作不是多对象中的每一个对象的方法,而是容纳这些对象的容器对象。
60? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心关联和导航
导航( navigability)是关联角色的一个属性
,表示从一个源对象沿着关联导航方向可以单向地到达一个目标类。在面向对象编程语言中,如果类 A要导航到类 B,则在类
A中将创建一个类 B的实例属性。
定义 A到 B带导航修饰关联的常见情况有以下几种:
A发送一个消息到 B;
A创建一个 B的实例;
A需要维护到 B的一个连接。
61? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心用户界面层设计类图
62? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心控制器 /处理层设计类图
63? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心业务 /领域层设计类图控制器 /处理层业务 /领域层持久化层
64? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心持久化层设计类图
65? 2008 BUPT TSEG 北京邮电大学 通信软件工程中心
10.4.5 startUp用例
大多数系统在启动过程中都要做一些系统初始化操作,所以可以设置一个 startUp用例,来完成相关初始化工作。
一般最后再进行 startUp用例的设计,以保证其包含所有初始化活动。
startUp用例的实现通过创建领域对象来实现。
初始化领域对象的选择原则是:选择领域对象的容器,或者聚集层次结构的根或临近根的类作为初始化领域对象的类。
在在线考试系统中,假如在系统初始化过程中将
“考题规格说明”信息读取到系统内存中,则在系统启动时,可以在 main函数中将 Rule对象实例化,并调用其方法将相关信息读入系统内存。