面向对象方法是一种运用对象、类、继承、封装、聚合、关联、消息、多态性等概念来构造系统的软件开发方法。
用类和对象作为系统的基本构成单位。对象对应问题域中的事物,其属性和操作刻画了事物的静态特征和动态特征,它们之间的继承关系、聚合关系、关联和消息如实地表达了问题域中事物之间实际存在的各种关系。
1.3.1 对象、属性、操作
对象是现实世界中某个实际存在的事物,它可以是有形的,比如一辆汽车,也可以是无形的,比如一项计划。对象是构成世界的一个独立单位。它具有自己的静态特征和动态特征。
对象是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位。对象由一组属性和施加于这些属性一组操作构成。
属性是用来描述对象静态特征的一个数据项。
操作是用来描述对象动态特征的一个动作序列。
对象标识就是对象的名字,有“外部标识”和“内部标识”之分。
1.3.2 抽象、类、一般类、特殊类
抽象与分类:忽略事物的非本质特征,只注意那些与当前目标有关的本质特征,从而找出事物的共性,叫做抽象。抽象是形成概念的基本手段。把具有共同性质的事物划分为一类,叫做分类。
类是具有相同属性和操作的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,其内部包括属性和操作两个主要部分。类的作用是用来创建对象,对象是类的一个实例。
一般类和特殊类的定义
定义1:如果类A具有类B的全部属性和全部操作,而且具有自己特有的某些属性或操作,则A叫做B的特殊类,B叫做A的一般类。一般类与特殊类又称父类与子类。
定义2:如果类A的全部对象都是类B的对象,而且类B中存在不属于类A的对象,则A是B的特殊类,B是A的一般类。
1.3.3 封装、继承、多继承
封装:把对象的属性和操作结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节。
封装的重要意义:使对象能够集中而完整地描述并对应一个具体的事物。体现了事物的相对独立性,使对象外部不能随意存取对象的内部数据,避免了外部错误对它的“交叉感染”。对象的内部的修改对外部的影响很小,减少了修改引起的“波动效应”。
继承:特殊类拥有其一般类的全部属性与操作,称作特殊类对一般类的继承。
由一组具有继承关系的类所组成的结构称作一般-特殊结构。它是一个以类为结点以继承关系为边的连通的有向图。继承关系的语义:“is a kind of"。
多继承:允许一个特殊类具有一个以上一般类的继承方式称作多继承
1.3.4 聚合与组合
聚合关系又称整体-部分关系,它是对象实例之间的一种关系。有时说两个类之间存在着整体-部分关系,是指一个类的对象实例以另一个类的对象实例作为组成部分。这种关系的语义是“has a”或“is a part of"。
由一组具有聚合关系的类所形成的结构称作整体-部分结构。它是一个以类为结点,以聚合关系为边的连通有向图。
紧密、固定的聚合方式又称为组合。
聚合与组合在UML中的表示:
两个或者多个类上的一个关系(即这些类的对象实例集合的笛卡儿积的一个子集合),其中的元素提供了被开发系统的应用领域中一组有意义的信息。
1.3.6 消息
消息:消息是向对象发出的服务请求。目前在大部分面向对象的编程语言中,消息其实就是函数(或过程)调用。但是,函数调用只是实现消息的方式之一,上述理解只适合于顺序系统。
更一般的定义:消息是对象之间在一次交互中所传送的信息。
1.3.7 多态
多态是指同一个命名可具有不同的语义。OO方法中,常指在一般类中定义的属性或操作被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。
实现机制:
1.4.1 面向对象方法与传统方法区别
1.4.2 面向对象方法的主要优点
1.5.1 与传统方法相比,面向对象方法有什么优点?
答:
1.5.2 封装的目的是什么?在面向对象方法中封装的目的是如何达到的?
答:
目的:降低对象之间的耦合度,避免外部错误对它的“交叉感染”;这样对象内部修改对外部的影响变小,减少了修改引起的“波动效应”。
如何达到:通过类的访问控制。
1.5.3 什么是面向对象方法?
答:
面向对象方法是一种运用对象、类、继承、封装、聚合、关联、消息、多态性等概念来构造系统的软件开发方法。
1.5.4 面向对象的基本思想?
答:
1.5.5 简述面向对象技术的三大机制。
答:
2.1.1 功能分解法
首先定义各种功能,然后把功能分解为子功能,同时定义功能/子功能之间的接口。对较大的子功能进一步分解,直到可给出明确的定义。
缺点:
2.1.2 数据流法(结构化分析)
其基本策略是跟踪数据流,即研究问题域中数据如何流动,以及在各个环节上进行何种处理,从而发现数据流和加工。得到的分析模型是数据流图(DFD),主要模型元素是数据流、加工、文件及端点,外加处理说明和数据字典。
优点:
缺点:
2.1.3 信息建模方法
由实体-关系法(E-R方法)发展而来。核心概念是实体和关系。实体描述问题域中的事物,关系描述事物之间在数据方面的联系,都可以带有属性。发展之后的方法也把实体称作对象,并使用了类型和子类型的概念,作为实体(对象)的抽象描述。
缺点:
2.1.4 面向对象方法
运用对象、类、继承、封装、聚合、关联、消息、多态性等概念来构造系统。把问题域中的事物抽象为对象,作为系统的基本构成单位其属性和操作刻画了事物的静态特征和动态特征——完整地刻画了问题域中事物。
用类作为对象的抽象描述,建立它们之间的继承、聚合、关联、消息等关系——如实地表达了问题域中事物之间的各种关系。
封装、继承、聚合、关联、消息通讯等原则符合人类的日常思维——使系统的复杂性得到控制。
因此,得到的系统模型可以直接映射问题域。
顾名思义,面向对象的分析(OOA),就是运用面向对象方法进行系统分析。首先,OOA是分析,是软件生命周期的一个阶段,具有一般分析方法共同具有的内容、目标及策略;但是,它强调运用面向对象方法进行分析,用面向对象的概念和表示法表达分析结果。基本任务是运用面向对象方法,对问题域和系统责任进行分析和理解,找出描述问题域及系统责任所需的对象,定义对象的属性、操作以及它们之间的关系。目标是建立一个符合问题域、满足用户需求的O0A模型。
系统边界:一个系统所包含的所有系统成分与系统以外各种事物的分界线。
参与者:在系统边界以外,与系统进行交互的事物人员、设备、外系统。
3.2.1 用况:
用况是对参与者使用系统的一项功能时所进行的交互过程的描述,其中包含由双方交替执行的一系列动作。
几点说明:
(1)一个用况只描述参与者对单独一项系统功能的使用情况;
(2)通常是平铺直叙的文字描述,UML也允许其他描述方式;
(3)陈述参与者和系统在交互过程中双方所做的事;
(4)所描述的交互既可能由参与者发起也可能由系统发起 ;
(5)描述彼此为对方直接地做什么事,不描述怎么做;
(6)描述应力求准确,允许概括,但不要把双方的行为混在一起;
(7)一个用况可以由多种参与者分别参与或共同参与;
启动用况:外部驱动力、满足前置条件——用况启动的前提
用况执行结果:用况执行完了,会有一个结果,这称为用况的后置条件
3.2.2 用况与参与者之间的关系
用况与参与者间的关联是参与者在用况中的参与(也就是参与者实例与用况实例之间的相互通信)。若没有进行特殊的说明,任何一方都可发送和接收消息。即交互是双向的,参与者能够产生对系统的请求,或系统要求参与者采取某些动作。这是参与者和用况之间的唯一关系。
3.2.3 用况之间的关系
(1)扩展关系:用带箭头的虚线加版型来表示
表示用况场景中的某个“支流”,由特定的扩展点触发而被启动。此时扩展表示“可选”,而不是“必需”,没有扩展用况,基本用况也是完整的;如果没有基本用况,扩展用况是不能单独存在的;如果有多个扩展用况,同一时间用况实例也只会使用其中的一个。
何时使用“扩展用况”:
a.表明用况的某一部分是“可选”的系统行为。
b.表明只在特定条件下才执行分支流。
c.表明有一组行为段,其中的一个或多个段可以在基本用况的扩展点处插入。
d.表明多个基本用况的可复用部分。
(2)包含关系:用一条带箭头的虚线加版型表示,特别用于用况模型,说明执行基本用况实例过程中插入的行为段。
包含用况代表在各种不同基本用况中复用的行为,包含用况表示的是“必需”而不是“可选”的行为;如果没有包含用况,基本用况是不完整的,如果没有基本用况,包含用况是不能单独存在的;基本用况可以控制与包含用况的关系,并依赖于执行包含用况所得的结果,基本用况与包含用况都不能访问对方的属性。
何时使用“包含用况”:
a.从基本用况中分解出的行为,它不需要了解基本用况,但是要向基本用况返回它执行的结果。
b.两个或更多的用况能提炼出共同的行为。
(3)泛化关系:用况之间的泛化关系就像类之间的泛化关系一样,子用况继承父用况的行为和含义。用一个指向父用况的带有封闭的空心箭头的实线来表示用况之间的泛化关系。
3.2.4 捕获用况
从系统功能角度捕获用况
(1)以穷举的方式检查用户对系统的功能需求是否能在各个用况中体现出来。
(2)以穷举的方式考虑每一个参与者与系统的交互情况,看看每个参与者要求系统提供什么功能,以及参与者的每一项输入信息将要求系统作出什么反映,进行什么处理。
(3)考虑对例外情况的处理。针对用况描述的基本流,要详尽地考虑各种其他的情况
(4)一个用况描述一项功能,这项功能不能过大。例如,把一个企业信息管理系统粗略地分为生产管理、供销管理、财务管理和人事管理等几大方面的功能,就显得粒度太大了,应该再进行细化。
(5)一个用况应该是一个完整的任务,通常应该在一个相对短的时间段内完成。如果一个用况的各部分被分配在不同的时间段,尤其被不同的参与者执行,最好还是将各部分作为单独的用况对待。
3.2.5 用况图示例
很多软件系统在一开始都需要登录,若用户登录成功,则可进入系统。如下以一个研究生学籍管理系统为例,描述四种登录方法。为了简化起见,假设此处仅描述登录、选课和查看学分这3项功能。
方案一:
由于选课和查看学分都需要登录,故专门设立一个“登录”用况。若登录成功,则可以进行选课,也可以进行查看学分。
登录的描述:
研究生启动系统;
系统提示研究生输入研究生证号和密码;
研究生输入研究生证号和密码;
系统进行验证,给出验证信息;
若通过,若该生选择选课
系统执行用况“选课”;
若通过,若该生选择查看学分
系统执行用况“查看学分”;
该方法的缺点是,
(1)必须要了解系统的所有其它模块,才能描述清楚“登录”用况。向系统增加新用况时,也要修改登录用况。从维护的角度看,有时会忘记对“登录”用况进行修改。
(2)“登录”用况的功能不单一。
方案二:
让所有的相关用况都包含登录用况。
如下为对用况“选课”的描述:
研究生启动系统,调用用况“登录”
若通过,系统执行用况“选课”的其余部分;
如下为对用况“查看学分”的描述:
研究生启动系统,调用用况“登录”
若通过,系统执行用况“查看学分”的其余部分;
其缺点为,对研究生要进行多次验证。——研究生执行系统的每项功能都要先登录。
方案三:
使用扩展,设计系统登录。
如下为对用况“登录”的描述:
研究生启动系统;
系统提示研究生输入研究生证号和密码;
研究生输入研究生证号和密码;
系统进行验证,给出验证信息;
若通过,若该生选择选课
系统在扩展点”选课”处执行用况“选课”;
若通过,若该生选择查看学分
系统在扩展点”查看学分”处执行用况“查看学分”;
该方案与方案一相比,对“登录”用况的描述要清楚一些。在增加新用况时,仅在登录用况中添加扩展点即可。
缺点:“登陆”用况的功能仍不单一。
方案四:
登录用况完全独立于其它用况。
如下为对用况“登录”的描述:
研究生启动系统;
系统提示研究生输入研究生证号和密码;
研究生输入研究生证号和密码;
系统进行验证,给出验证信息;
如下为对用况"选课”的开始部分的描述:
若研究生通过了登录且选择了选课,
系统开始执行用况“选课”;
使用该方法,必须要在“选课”用况和“查看学分”用况中指定前置条件:只有在登录成功后才能执行自己。
3.3.1 用况之间包含关系、扩展关系与泛化关系有相同之处吗?
答:
有相同之处。这三种关系都是将用况中的一些动作序列抽取出来,放到另外一个用况中,使得用况的描述和用况之间的关系更加明确,提高复用性。
3.3.2 论述用况图在面向对象方法中的地位。
答:
用况图用于对系统的功能以及与系统进行交互的外部事物建模。通过找出与系统交互的外部事物,并说明它们如何与系统交互,易于对系统进行探讨和理解。这样,用户能够理解未来的系统,开发者也能够正确地理解需求并实现系统。用况图是对所捕获的需求的规范化描述,是进行面向对象分析的基础,对面向对象设计阶段的人机交互设计和系统测试来说,也是十分重要的。
3.3.3 通常自动售货机会按用户的要求进行自动售货。供货员会巡查向其内供货,取款员会定时取款。请建立用况图,并描述各个用况。
答:
4.1.1 对象
对象(object)是系统中用来描述客观事物的一个实体,它是构成系统的一个基本单位,由一组属性和施加于这组属性的一组操作构成。
主动对象( active object)——至少有一个操作不需要接收消息就能主动执行的对象,用于描述具有主动行为的事物
被动对象(passive object) ——每个操作都必须在消息的驱动下才能执行的对象。
4.1.2 类
类(class)是具有相同属性和操作的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述,它由一个类名、一组属性和一组操作构成。
类和对象的关系——集合与成员,对象是类的实例。
不直接创建对象实例的类称为抽象类(abstract class)
主动对象的类叫做主动类( active class)
4.2.1 研究问题域
4.2.2 正确地运用抽象原则
4.2.3 策略与启发
(1)考虑问题域
(2)考虑系统边界
考察在系统边界以外与系统交互的各类参与者考虑通过那些对象处理这些参与者的交互
(3)考虑系统责任
检查每一项功能需求是否已有相应的对象提供,发现遗漏的对象
4.2.4 审查与筛选
(1)舍弃无用的对象
二者都不是——无用
(2)对象的精简
(3)与实现条件有关的对象
例如:与图形用户界面(GUI)数据管理系统硬件及操作系统有关的对象推迟到OOD考虑。
4.3.1 将对象抽象为类,用类表示它的全部对象
4.3.2 审查和调整
4.3.3 类的命名
4.4.0 属性
属性是用来描述对象静态特征的一个数据项。
实例属性(instance attribute)和类属性(class attribute)的区别
例如:
仪表类输入电压、功率及各种规定的质量指标——类属性
编号、出厂日期、精度等实际性能参数——实例属性
4.4.2 审查与筛选
4.4.3 推迟到OOD考虑的问题
规范化问题
对象标识性能问题
4.4.4 属性的命名与定位
命名:原则与类的命名相同
定位:针对所描述的对象,适合全部对象实例
4.5.0 操作
操作是用来描述对象动态特征(行为)的一个动作序列。
被动操作(passive operation) :
只有接收到消息才能执行的操作编程语言中的函数、过程等被动成分
主动操作( active operation) :
不需要接收消息就能主动执行的操作编程语言中的进程、线程等主动成分
4.5.1 对象行为分类
4.5.2 策略与启发
4.5.3 审查与调整
4.5.4 认识对象的主动行为
4.5.6 操作的命名和定位
4.5.7 接口
接口( interface)是由一组操作所形成的一个集合,它由一个名字和代表其中每个操作的特征标记构成。
特征标记(signature)代表了一个操作,但并不具体地定义操作的实现
特征标记:=<操作名>(|<参数>:<类型> {,参数>:<类型>}) [:<返回类型>]
表示方法:
接口与类的关系:
接口由某些类实现(提供),由另外某些类使用(需要),前者与接口的关系称为实现(realization),后者与接口的关系称为使用(use)
接口与类的区别:
引入接口概念的好处:
在接口的使用者和提供者之间建立了一种灵活的衔接机制,有利于对类、构件等软件成分进行灵活的组装和复用。
将操作的声明与实现相分离,隔离了接口的使用者和提供者的相互影响。使用者只需关注接口的声明,不必关心它的实现;提供者不必关心哪些类将使用这个接口,只是根据接口的声明中所承诺的功能来实现它,并且可以有多种不同的实现。接口概念对描述构件之间的关系具有更重要的意义
如何发现?
审查与调整
简化
多态:
多态是指同一个命名可具有不同的语义。OO方法中,常指在一般类中定义的属性或操作被特殊类继承之后,可以具有不同的数据类型或表现出不同的行为。
4.6.2 整体-部分结构(a part of)
在连接符两端通过数字或者符号给出关系双方对象实例的数量约束,称为多重性(multiplicity)
如何发现?
考察问题域中各种具有构成关系的事物
审查和筛选
(1)是否属于问题域? 例:公司职员与家庭
(2)是不是系统责任的需要? 例:员工与工会
(3)部分对象是否有一个以上的属性? 例:汽车与车轮(规格)
(4)是否有明显的整体-部分关系? 例:学生与课程
高级技巧
4.6.3 关联
(1)带有属性和操作的关联
问题:增加了概念的复杂性,缺乏编程语言支持
解决方法:
复杂关联表示法的转换
(2) n元关联
在模型中,把n元关联定义为一个类,并定义它与原有的各个类之间的关系——都是二元关联。
(3)一个类在一个关联中多次出现
例:课程实习中每两名学生在一台设备上合作完成一个题目。
1)若系统要求记录和查阅哪两名学生是合作者
建立学生类到它自身的关联(如同城市之间有航线)是一个二元关联,其中学生类在关联中出现了两次
2)如果还要记录每组学生的实习题目和使用的设备
建立学生、题目、设备三个类之间的4元关联学生类在这个关联中出现了两次
加入该系统的多重性要求是:
4.6.4 消息
(1)什么是消息( message)
4.6.5 依赖
继承、聚合、关联、消息这四种关系中都已经蕴涵了依赖的含义,不需要再用依赖关系再做重复的表示,除了上述关系之外,在OO建模中没有多少重要的信息必须用依赖关系表达
4.7.1 论述类与对象之间的关系以及关联与链之间的关系。这些概念之间还有什么关系吗?
答:
对象是具有明确语义边界并封装了状态和行为的实体,由一组属性和作用在这组属性上的一组操作构成;类是对具有相同属性和操作的一组对象的抽象描述,也就是说它为属于该类的全部对象提供了统一的抽象描述。对象是类的实例。
关联是两个或两个以上类间的一种关系,其中的元素提供了被开发系统的应用领域中的一组有意义的信息。如果类的对象之间通过属性有连接关系,那么这些类之间的语义关系就是关联。链表示对象间的物理与概念联结。链是关联的实例,关联是链的抽象。
关联是类之间的静态联系,链是对象之间的静态联系。两个存在有关联关系的类被实例化成对象后,类之间的关联就被实例化为链。
4.7.2 针对下述问题,建立一个类图:有两种顾客,一种是常客,享受公司的一些优惠待遇;另一种是散户。
答:
4.7.3 面包是由面包片组成的。讨论面包及其切片之间的关系。
答:
面包与其切片之间是组合的关系。
组合是聚合的一种形式,它要求一个部分类的对象在一个时刻至多属于一个整体类的对象,且整体类的对象管理它的部分类的对象。
面包与面包片是“整体—部分”的关系;另一方面,一片面包片只能属于一个面包,当这个面包“消亡”(被吃掉)后,面包片也就不存在了。因此应该是组合关系。
4.7.4 在类图中,主要的类间关系有哪几种,各代表什么含义?
答:
关联、聚合、组合、泛化、依赖。
5.1.1 概念
顺序图是一种详细地表示对象之间行为关系的图。它按时间顺序展现了一组相互协作的对象在完成一项功能时所执行的操作,以及它们之间所传送的消息,从而清晰地表示对象之间的行为关系以及操作和消息的时序关系。
顺序图是二维的:垂直方向表示时间,水平方向表示不同的对象或参与者。
通常时间维由上到下(根据需要,也可以由下到上)。通常只有时间顺序是重要的,但在实时应用中时间轴是能度量的。对象的水平顺序并不重要,顺序可以是任意的。
5.1.2 对象生命线
把对象表示成称之为“生命线”的垂直虚线。生命线代表一个对象在特定时间内的存在。
在图的顶部(第一个箭头之.上)放直在文互开始时就存在的对象,而在整个交巨完成时仍然存在的对象的生命线,要延伸超出最后一个箭头。
如果一个对象在图中所规定的时|间段被创建,那么就把创建对象的箭头的头部在对象符号上。如果对象在图中被销毁,那么用—个大的“X”标记它的析构,该标记或者放在引起析构的箭头处,或者放在从被销墅的对象最终返回的箭头处(在自析构的情况下)。
生命线可以分裂成两条或更多条并发的生命线,以表示条件性。这样的每一个生命线对应于交互中的一个条件分支。生命线可以在某个后续点处合并。
5.1.3 执行规约
执行规约表示一个对象直接或者通过从属例程执行一个行为的时期。它既表示了行为执行的持卖时间,也表示了调用者与被调用者之间的控制关系。
用一个窄长的矩形表示执行规约,矩形顶端和它的开始时刻对齐,未端和它的结束时刻对齐。
执行规约符号的顶端画在进入的箭头的端(开始该动作的那个前头),低端画在返回的箭头的尾部。
当一个对象处于执行规约期时,该对象能够响应或发送消息,执行对象或活动。
当一个对象不处于执行规约期时,该对象不做什么事情,但它是存在的,等待新的消息执行规约它。
若调用一个对象的另一个操作,第二个执行规约符号画在第一个符号稍微靠右的位置。
5.1.4 消息
消息是对象之间的通讯的规格说明,这样的通讯用于传输将发生的活动所需要的信息——控制信息(如调用)和所使用的数据的规格说明。
一个消息会调用另一个对象的操作,调用本对象的操作,向另一个对象发送一个信号,创建或者撤消一个对象(可以自己销毁自己),还可能向调用者返回一个结果。
把消息表示为从一个对象生命线到另一个对象生命线的一个水平实线箭头,即从源对象指向目标对象,以触发目标对象中的特定操作。对于对象到自身的消息,箭头就从同一个对象符号开始和结束。
用消息(操作或信号)的名字及其参数值或者参数表达式标示箭头。
消息分支
把分支画成从一个点出发的多个箭头,每个箭头由监护条件标示。依据监护条件是否互斥,这个结构可以表达条件或者并发。
消息循环
标以持续的条件:*[条件]方框围起来的区域为重复的。
5.1.5 顺序图中的结构化控制
序列性的消息能很好地说明单一的线性的序列,但是我们通常需要展示条件和循环。有时候我们想要展示多个序列的并行执行。在顺序图中用结构化控制操作符能展示这种高层控制。
为了表示顺序图的边界,可以把顺序图用一个封闭的矩形包围起来,并在矩形的左上角放一个小五边形。在这个小五边形内先写上sd,再后面写出图的名字。
对每个子顺序图加上一个矩形区域作为外框,再在其左上角放一个小五边形,在这个小五边形内写上用来表明控制操作符的类型的文字。
可选执行标签是opt。如果控制进入该操作符标识的交互区域时监护条件成立,那么执行该交互区域。监护条件是一个用方括号括起来的布尔表达式,它要出现在交互区域内部第一条生命线的顶端,在其中可以引用该对象的属性。
条件执行标签为alt。用水平虚线把交互区域分割成几个分区,每个分区表示一个条件分支并有一个监护条件。如果一个分区的监护条件为真,就执行这个分区,但最多只能执行一个分区。如果有多于一个监护条件为真,那么选择哪个分区是不确定的。若没有应对措施,在模型中要避免这种情况。如果所有的监护条件都不为真,那么控制流将跨过这个交互区域而继续执行。其中的一个分区可以用特殊的监护条件[else],这意味着如果其他所有区域的监护条件都为假,就执行该分区。
并行执行标签是par。用水平虚线把交互区域分割为几个分区。每个分区表示一个并发计算。当控制进入交互区域时并发地执行所有的分区;在并行分区都执行完后,那么该并行操作符标识的交互区域也就执行完毕。每个分区内的消息是顺序执行的。需要指出的是,并发并不总是意味着物理上的同时执行。并发其实是说两个动作没有协作关系,而且可按任意次序发生。如果它们确实是独立的动作,那么它们还可以交叠。
循环(迭代)执行标签是loop。在交互区域内的顶端给出一个监护条件。只要在每次迭代之前监护条件成立,那么循环主体就会重复执行。一旦在交互区域顶部的监护条件为假,控制就会跳出该交互区域。
5.1.6 建立顺序图
5.2.1 概念
“通信图集中于生命线之间的交互,中心问题是其内部组织的体系结构以及如何与消息传输协调。消息的次序通过其序列号给出。”
“通信图与简单的顺序图是一致的,简单的顺序图是指,没有交互使用和组合片段等结构机制,并且假设不会发生消息超越(即在一个给定的消息集合内接收消息的次序与发送消息的次序不同)或者与之无关。”
5.3.1 概念
活动图是一种描述系统行为的图,它把一项行为表示成一个可以由计算机、人或者其他执行者执行的活动,通过给出活动中的各个动作以及动作之间的转移关系来描述系统的行为。
活动图由结点(node)和边(edge)两种基本元素构成。
5.3.2 基本元素
5.3.3 例子
5.4.1 概念
状态图:
状态图是一种描绘系统中的对象(或者其他实体)在其生命期内所经历的各种状态、状态之间的转移、发生转移的动因、条件及活动的模型图。
状态(state):
“对象生命期中的一种条件或者情形,在此期间它满足某些条件,执行某些活动,或者等待某些事件。”“状态是对一种状况的模型表示,在此期间保持了某些(通常是固有的)条件。”
伪状态(pseudo state):
伪状态实际上并不是一种状态,只是为了加强状态机图的可视化效果而引入的一些图形符号,都是结点(顶点)型的图形成分。
转移(transition):
组合状态(composite state):
由若干状态组织在一起所形成的状态。包含在组合状态内部的状态称为子状态内部不包含其他状态的状态称为简单状态
5.4.2 示例
5.5.1 概念
包(package)是一种将其他模型元素组织起来,形成较大粒度的系统单位的通用机制。
5.5.2 包之间的关系
5.5.3 建立包图
5.6.1 使用信用卡可以在AMT机上进行取款,针对一次取款,建立类图、顺序图。注意ATM机是与银行连网的。
要求:
(1)绘制一个类图(不要过于复杂)
(2)绘制顺序图
答:
(1)
5.6.2 几台计算机共用一台打印机,打印机由打印服务器管理,请建立顺序图。
答:
5.6.4 在图书馆中,购入的书在半个月内为新书,以后为旧书。书无论新旧,都可以向外借阅。针对上述要求建立状态机图。
答:
6.2.1 OOD模型
包括五个方面:
6.2.2 OOD过程
OOD过程与OOD模型中五个部分相对应的五项活动组成
如果已存在一些可复用的类,而且这些类既有分析、设计时的定义,又有源程序,那么,复用这些类即可提高开发效率与质量。
7.2.1 概念
一般类:包含多个类中一般特征的类
共同协议:多个类具有的共同特征(属性和操作)
7.2.2 适用情况
按照语法:[ 可见性 ] 属性名 [ ‘:’ 类型 ] [ ‘=’ 初始值 ] 对属性的定义进行完善。
可见性包括:私有——‘-’、保护——‘#’、公有——‘+’、······
类型包括:整型——‘int’、浮点型——‘float’、字符串——‘String’、······
7.7.1 软件复用可以采用类的继承方式和类的聚合方式,比较两者的优缺点。
答:
聚合复用优点:封装性好、耦合性低、满足单一职责原则
缺点:系统复杂性提高
类继承复用优点:容易添加新的实现,容易进行修改和扩展类
缺点:破坏了封装性,耦合性高
7.7.2 简述怎样发现类之间的继承关系。
答:
为候选的类有可能和它的父类、子类在谈话中同时被发现。系统分析员意识到某个类的属性和操作也许能被运用到其他多个类当中去。另一种可能的情况是系统分析员注意到两个或者多个类可能具有相同的属性和操作数.
7.7.3 简述类继承和接口继承的区别,我们应该尽量使用哪一种?
答:
类继承根据一个对象的实现定义了另一个对象的实现。简而言之,它是代码和表示的共享机制。然而,接口继承描述了一个对象什么时候能被用來替代另一个对象。
类继承是派生中的类将继承父类的所有属性和方法,并且可以在派生类里添加自己的属性和方法,而接口继承则是在接口里只定义接口的方法,没有属性,并且方法不能实现,只有在派生他的类才实现该方法。类继承是编译的时候新建对象, 而接口实例是在运行时刻创建对彖。我们应该尽量使用接口继承,类继承会产生类爆炸现象
人机交互部分是OOD模型的组成部分之一,突出人如何命令系统以及系统如何向用户提交信息。设计人机交互就是要设计输入和输出。
8.5.1 人机交互部分的组成部分。
答:
设计用户界面模型、该模型中的类、对象和提供实现人机交互操作的接口函数。
控制驱动部分是OOD模型的外围组成部分之一,由系统中全体主动类构成。这些主动类描述了整个系统中所有的主动对象,每个主动对象是系统中一个控制流的驱动者。
控制流(control flow)———进程( process)和线程( thread)的总称,有多个控制流并发执行的系统称作并发系统(多任务系统)
9.4.1 进程和线程的区别?
答:进程是程序执行过程中的动态映像,是操作系统进行资源分配和保护的基本单位。线程是进程中的一条执行流程,同一进程中的线程共享进程的资源,线程是操作系统进行处理机调度的基本单位。
9.4.2 进程间和线程间的通信方式?
答:
进程:
线程:
数据接口部分是OOD模型中负贡与具体的数据管理系统衔接的外围组成部分,它为系统中需要长久存储的对象提供了在选定的数据管理系统中进行数据存储与恢复的功能。
大部分实用的系统都要处理数据的永久存储问题,数据保存于永久性存储介质,在数据管理系统的支持下实现其存储、检索和维护。在面向对象的系统中,数据的存储表现为对象存储
数据库:数据库是长期存在计算机内、有组织、可共享的数据集合。
数据管理系统:实现数据存储、检索、管理与维护的系统,包括文件系统和数据库管理系统两大类(文件系统file system、关系型数据库管理系统RDBMS、面向对象的数据库管理系统OODBMS)
数据库管理系统(DBMS) :用于建立、使用和维护数据库的软件。它对数据库进行统一的管理和控制,以保证数据库的安全性和完整性。
10.2.1 文件系统
通常是操作系统的一部分,管理外存空间的文件数据,提供存储、检索、更新、共享和保护等功能。
文件结构
文件系统提供的支持
编程语言可以提供更方便的文件定义与使用方式
优点:
缺点:
10.2.2 关系型数据库管理系统
10.2.3 面向对象数据库
10.3.1 对象在内存空间和文件空间的映像
如何看待用文件系统存储对象
从应用系统的对象到文件记录的不同映射方式
10.3.2 对象在文件中的存放策略
1)基本策略:
把由每个类直接定义、需要永久存储的全部对象实例存放在一个文件中;每个对象实例的全部属性作为一个存储单元,占用该文件的一个记录。
2)提高检索效率——在对象和文件记录之间建立有规律的映射关系
10.3.4 问题域部分的修改
增加一个一般类来定义它们,作为共同协议,供所有的永久对象类继承,每个永久对象类都要增加请求存储和恢复所需的属性和操作,以便向数据接口部分发出请求。
10.3.1 对持久类的存储设计
10.3.2 对关系的存储设计
从应用系统到数据库,从内存空间到外存空间,数据模型都是一致的。因此,几乎不要为此再做更多的设计工作。
类图中的类一般不需要类似于规范化的改造,也不需要专门设计专门负责对象保存与恢复的对象类
主要考虑:如何用OODBMS提供的数据定义语言、数据操纵语言和其它编程语言来实现OOD模型——实现类和对象的定义和对数据库的访问,必要时要根据语言的功能限制对类图做适当的修改。
10.4.1 数据库系统、数据库和数据库管理系统的区别是什么?
答:
数据库系统(DBS)包括数据库(DB)和数据库管理系统(DBMS),数据库是存储在计算机内、有组织的、可共享的数据和数据对象的集合,这种集合按照一定的数据模型组织、描述和长期存储,同时能以安全和可靠的方法进行数据的检索和存储。数据库管理系统是数据库系统的核心软件。数据库管理系统可以借助操作系统完成对硬件的访问,并能对数据库的数据进行存取、维护和管理。
11.1.1 概念
11.1.2 构件的内部结构
11.1.3 对构件的行为建模
11.1.4 对构件的实现建模
11.2.1 概念
11.2.2 对系统的部署建模
11.3.1 构件图的作用。
答:
使系统人员和开发人员能够从整体上了解系统的所有物理部件,同时,也使我们知道如何对构件进行打包,以便交付给最终客户,最后构件图显示了被开发系统所包含的构件之间的依赖关系。
使用构件图可以清楚地看出系统的结构和功能。方便项目组的成员制定工作目标和了解工作情况,最重要的是使用构件图有利于软件的复用。
设计原则名称 | 设计原则简介 | 重要性 |
---|---|---|
单一职责原则 | 类的职责要单一,不能将太多的职责放在一个类中 | ★★★★☆ |
开闭原则 | 软件实体对扩展是开放的,但对修改是关闭的,即在不修改一个软件实体的基础上去扩展其功能 | ★★★★★ |
里氏代换原则 | 在软件系统中,一个可以接受基类对象的地方必然可以接受一个子类对象 | ★★★★☆ |
依赖倒转原则 | 要针对抽象层编程,而不要针对具体类编程 | ★★★★★ |
接口隔离原则 | 使用多个专门的接口来取代一个统一的接口 | ★★☆☆☆ |
合成复用原则 | 在系统中应该尽量多使用组合和聚合关联关系,尽量少使用甚至不使用继承关系 | ★★★★☆ |
迪米特法则 | 一个软件实体对其他实体的引用越少越好,或者说如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用,而是通过引入一个第三者发生间接交互 | ★★★☆☆ |
引入外观角色之后,用户只需要直接与外观角色交互,用户与子系统之间的复杂关系由外观角色来实现,从而降低了系统的耦合度。
外部与一个子系统的通信必须通过一个统一的外观对象进行,为子系统中的一组接口提供一个一致的界面,外观模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
外观模式又称为门面模式,它是一种对象结构型模式。
外观模式由三个角色组成:
外观角色:外观模式的核心。它被客户角色调用,因此它熟悉子系统的功能。其内部根据客户角色已有的需求预定了几种功能组合。
子系统角色:实现子系统的功能,对它而言,外观角色就和客户角色一样是未知的,它没有任何外观角色的信息和链接。
客户角色:调用外观角色来完成要得到的功能
根据“单一职责原则”,在软件中将一个系统划分为若干个子系统有利于降低整个系统的复杂性,一个常见的设计目标是使子系统间的通信和相互依赖关系达到最小,而达到该目标的途径之一就是引入一个外观对象,它为子系统的访问提供了一个简单而单一的入口。
外观模式也是“迪米特法则”的体现,通过引入一个新的外观类可以降低原有系统的复杂度,同时降低客户类与子系统类的耦合度。
在外观模式中,通常只需要一个外观类,并且此外观类只有一个实例,换言之它是一个单例类。
在很多情况下为了节约系统资源,一般将外观类设计为单例类**。**当然这并不意味着在整个系统里只能有一个外观类,在一个系统中可以设计多个外观类,每个外观类都负责和一些特定的子系统交互,向用户提供相应的业务功能。
不要通过继承一个外观类在子系统中加入新的行为,这种做法是错误的。
外观模式的用意是为子系统提供一个集中化和简化的沟通渠道,而不是向子系统加入新的行为,
抽象外观类的引入
外观模式最大的缺点在于违背了“开闭原则”,当增加新的子系统或者移除子系统时需要修改外观类,可以通过引入抽象外观类在一定程度上解决该问题,客户端针对抽象外观类进行编程。
对于新的业务需求,不修改原有外观类,而对应增加一个新的具体外观类,由新的具体外观类来关联新的子系统对象,同时通过修改配置文件来达到不修改源代码并更换外观类的目的。
在软件开发中,为了解决接口不一致的问题,两个软件模块之间往往也需要通过一个适配器类Adapter进行“适配”。这样的模式叫做适配器设计模式。
通常情况下,客户端可以通过目标类的接口访问它所提供的服务。
有时,现有的类可以满足客户类的功能需要,但是它所提供的接口不一定是客户类所期望的,这可能是因为现有类中方法名与目标类中定义的方法名不一致等原因所导致的。
在这种情况下,现有的接口需要转化为客户类期望的接口,这样保证了对现有类的重用。如果不进行这样的转化,客户类就不能利用现有类所提供的功能,适配器模式可以完成这样的转化。
适配器提供客户类需要的接口,适配器的实现就是把客户类的请求转化为对适配者的相应接口的调用。
也就是说:当客户类调用适配器的方法时,在适配器类的内部将调用适配者类的方法,而这个过程对客户类是透明的,客户类并不直接访问适配者类。
因此,适配器可以使由于接口不兼容而不能交互的类可以一起工作。
该模式可以分为两种,分别为类适配器模式(Class Adapter Pattern)和对象适配器模式(Object Adapter Pattern)。
示例:
某公司购买了一个用于验证客户信息的离架产品类InfoValidation,但是卖方没有提供源代码。该类可以用于检查客户输入的信息,包含验证姓名、地址、电话区号和手机号码等功能。如果还需要增加一个验证社会安全号(SSN)的功能,则可以使用类适配器模式来实现。
解析:
示例:
使用对象适配器实现字符串序列排序。要求从一个.txt文件读入一些英文字符串,并且对这些字符串进行排序。
这里已有一个类FileInput,其主要功能包含从一个文件中读入字符串;另外,在一个Java类库中有一个Arrays,其中包含功能sort,用于对多个字符串进行排序。
解析:
类适配器模式与对象适配器模式的区别:
在Java语言中,使用对象适配器模式可以把多种不同的源类都适配到同一个目标接口,而使用类的适配器模式是做不到这一点的。
如果一个被适配源类中有大量的方法,使用类适配器模式比较容易,只需要让Adapter类继承被适配的源类即可。而此时使用对象适配器模式则要在Adapter类中明确写出Target角色中的每个方法,并且在每个方法中要调用被适配的源类中的相应的方法。
优点:
将目标类和适配者类解耦,通过引入一个适配器类来重用现有的适配者类,而无须修改原有代码。
增加了类的透明性和复用性,将具体的实现封装在适配者类中,对于客户端类来说是透明的,而且提高了适配者的复用性。
灵活性和扩展性都非常好,通过使用配置文件,可以很方便地更换适配器,也可以在不修改原有代码的基础上增加新的适配器类,完全符合“开闭原则”。
由于类适配器是适配者类的子类,因此可以在类适配器中置换一些适配者的方法,使得适配器的灵活性更强。
一个对象适配器可以把多个不同的适配者适配到同一个目标,也就是说,同一个适配器可以把适配者类和它的子类都适配到目标接口。
缺点:
对于Java、C#等不支持多重继承的语言,一次最多只能适配一个适配者类,而且目标抽象类只能为抽象类,不能为具体类,其使用有一定的局限性,不能将一个适配者类和它的子类都适配到目标接口。
与类适配器模式相比,要想置换适配者类的方法就不容易。如果一定要置换掉适配者类的一个或多个方法,就只好先做一个适配者类的子类,将适配者类的方法置换掉,然后再把适配者类的子类当做真正的适配者进行适配,实现过程较为复杂。
适用场合:
适配器模式的扩展:
策略模式定义了一系列算法,将每一个算法封装起来,并且使它们之间可以相互替换。策略模式让算法的变化不会影响到使用算法的客户。
策略模式是一个比较容易理解和使用的设计模式,策略模式是对算法的封装,它把算法的责任和算法本身分割开,委派给不同的对象管理。策略模式通常把一个系列的算法封装到一系列的策略类里面,作为一个抽象策略类的子类。用一句话来说,就是“准备一组算法,并将每一个算法封装起来,使得它们可以互换”。
优点:
缺点:
这种模式称为“被观察者/观察者”,每一个模块都允许其他模块向自己所发送的某些消息表明兴趣。当某一模块发出某一事件时,它自动将这些事件发布给那些曾经向自己注册过此事件的模块。
观察者模式的各组成部分说明如下:
观察者模式的工作原理如下:
在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时候我们需要一个工厂可以提供多个产品对象,而不是单一的产品对象。
产品等级结构:——同一产品类型,不同工厂生产
产品等级结构即产品的继承结构,如一个抽象类是电视机,其子类有海尔电视机、海信电视机、TCL电视机,则抽象电视机与具体品牌的电视机之间构成了一个产品等级结构,抽象电视机是父类,而具体品牌的电视机是其子类。
产品族:——同一工厂生产,不同产品类型
在抽象工厂模式中,产品族是指由同一个工厂生产的,位于不同产品等级结构中的一组产品,如海尔电器工厂生产的海尔电视机、海尔电冰箱,海尔电视机位于电视机产品等级结构中,海尔电冰箱位于电冰箱产品等级结构中。
抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。抽象工厂模式又称为Kit模式,属于对象创建型模式。
示例:
一个电器工厂可以产生多种类型的电器,如海尔工厂可以生产海尔电视机、海尔空调等,TCL工厂可以生产TCL电视机、TCL空调等,相同品牌的电器构成一个产品族,而相同类型的电器构成了一个产品等级结构。
请使用抽象工厂模式模拟该场景。
解析:
抽象工厂模式的可扩展性:
增加新的工厂符合开闭原则,增加新类型的产品不符合开闭原则。
优点:
抽象工厂模式隔离了具体类的生成,使得客户并不需要知道什么被创建。由于这种隔离,更换一个具体工厂就变得相对容易。
所有的具体工厂都实现了抽象工厂中定义的那些公共接口,因此只需改变具体工厂的实例,就可以在某种程度上改变整个软件系统的行为。另外,应用抽象工厂模式可以实现高内聚低耦合的设计目的,因此抽象工厂模式得到了广泛的应用。
当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象。这对一些需要根据当前环境来决定其行为的软件系统来说,是一种非常实用的设计模式。
增加新的具体工厂和产品族很方便,无须修改已有系统,符合“开闭原则”。
缺点:
在添加新的产品对象时,难以扩展抽象工厂来生产新种类的产品,这是因为在抽象工厂角色中规定了所有可能被创建的产品集合,要支持新种类的产品就意味着要对该接口进行扩展,而这将涉及到对抽象工厂角色及其所有子类的修改,显然会带来较大的不便。
开闭原则的倾斜性(增加新的工厂和产品族容易,增加新的产品等级结构麻烦)
适用场合:
一个系统不应当依赖于产品类实例如何被创建、组合和表达的细节,这对于所有类型的工厂模式都是重要的。
系统中有多于一个的产品族,而每次只使用其中某一产品族。
属于同一个产品族的产品将在一起使用,这一约束必须在系统的设计中体现出来。
系统提供一个产品类的库,所有的产品以同样的接口出现,从而使客户端不依赖于具体实现。
抽象工厂模式包含四个角色:
在简单工厂模式中,只提供了一个工厂类,该工厂类处于对产品类进行实例化的中心位置,它知道每一个产品对象的创建细节,并决定何时实例化哪一个产品类。
简单工厂模式最大的缺点是当有新产品要加入到系统中时,必须修改工厂类,加入必要的处理逻辑,这违背了“开闭原则”。
在简单工厂模式中,所有的产品都是由同一个工厂创建,工厂类职责较重,业务逻辑较为复杂,具体产品与工厂类之间的耦合度高,严重影响了系统的灵活性和扩展性。
为克服简单工厂方法模式的不足,人们试图改善工厂类结构以解决这一问题。
软件设计者们发现,可以将简单工厂方法模式中单一的工厂类改写为一个层次类来解决这个问题。
工厂方法模式是简单工厂模式的进一步抽象和推广。由于使用了面向对象的多态性,工厂方法模式保持了简单工厂模式的优点,而且克服了它的缺点。
在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责哪一个产品类被实例化这种细节,
这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体产品对象以及一个具体工厂对象,原有工厂对象不需要进行任何修改,也不需要修改客户端,很好地符合了“开闭原则”。而简单工厂模式在添加新产品对象后不得不修改工厂方法,扩展性不好。
工厂方法模式退化后可以演变成简单工厂模式。
优点:
在工厂方法模式中,工厂方法用来创建客户所需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节,用户只需要关心所需产品对应的工厂,无须关心创建细节,甚至无须知道具体产品类的类名。
基于工厂角色和产品角色的多态性设计是工厂方法模式的关键。它能够使工厂可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。工厂方法模式之所以又被称为多态工厂模式,是因为所有的具体工厂类都具有同一抽象父类。
使用工厂方法模式的另一个优点是在系统中加入新产品时,无须修改抽象工厂和抽象产品提供的接口,无须修改客户端,也无须修改其他的具体工厂和具体产品,而只要添加一个具体工厂和具体产品就可以了。这样,系统的可扩展性也就变得非常好,完全符合“开闭原则”。
缺点:
在添加新产品时,需要编写新的具体产品类,而且还要提供与之对应的具体工厂类,系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译和运行,会给系统带来一些额外的开销。
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度,且在实现时可能需要用到DOM、反射等技术,增加了系统的实现难度。
适用场景
一个类不知道它所需要的对象的类:在工厂方法模式中,客户端不需要知道具体产品类的类名,只需要知道所对应的工厂即可,具体的产品对象由具体工厂类创建;客户端需要知道创建具体产品的工厂类。
一个类通过其子类来指定创建哪个对象:在工厂方法模式中,对于抽象工厂类只需要提供一个创建产品的接口,而由其子类来确定具体要创建的对象,利用面向对象的多态性和里氏代换原则,在程序运行时,子类对象将覆盖父类对象,从而使得系统更容易扩展。
将创建对象的任务委托给多个工厂子类中的某一个,客户端在使用时可以无须关心是哪一个工厂子类创建产品子类,需要时再动态指定,可将具体工厂类的类名存储在配置文件或数据库中。
12.8.1 抽象工厂模式案例
使用工厂方法模式设计一个系统日志记录器,该系统日志记录器要求支持多种日志记录方式,如文件日志记录(FileLog)、数据库日志记录(DatabaseLog)等,每种记录方式均具有writeLog()方法记录数据,客户端(Client)可选择日志记录方式(logType)通过调用工厂类(LogFactory)中的createLog()方法创建日志(Log)对象,
请按要求画出类图及其关键属性和操作。
12.8.2 适配器模式案例
某公司欲开发一款儿童玩具汽车(Car),为了更好地吸引小朋友的注意力,该玩具汽车在移动(move)过程中伴随着灯光闪烁(twinkle)和声音提示(sound),在该公司以往的产品(OldProduct)中已经实现了控制灯光闪烁和声音提示的程序,为了重用先前的代码并且使得汽车控制软件具有更好的灵活性和扩展性,使用适配器(CarAdapter)模式设计该系统,
请按要求画出类图及其关键操作。
解析:
12.8.3 外观模式案例
在金融机构中,当有客户(Client)前来抵押贷款mortgage()时,需通过抵押系统(Mortgage)对客户进行合格性验证isQualified(),只有验证通过后才能进行抵押贷款。
抵押系统的合格性验证需要三个子系统同时工作:身份验证(Authentication)子系统确认客户身份是否合法isLegal()、信用(Credit)子系统查询其信用是否良好isCredible()以及贷款(Loan)子系统查询客户是否有贷款劣迹hasBadLoans()。只有这三个子系统都通过时才能通过合格性验证。
使用外观模式模拟该过程,请按要求画出类图及其关键属性和操作。
解析:
12.8.4 策略模式案例
现有一种玩具,它可以模拟三种动物(Animal)的叫声:狗叫(Dog)、猫叫(Cat)和青蛙叫(Frog),每一种动物都有cry()方法用于实现发出叫声的操作。玩具类(Toy) 使用setAnimal()方法设置动物,并使用属性currentAnimal记录玩具当前模拟的动物,使用 run()方法来调用动物的cry()方法使玩具发出叫声。为将来能模拟更多的动物,采用策略模式设计该系统,请按要求画出类图及其关键属性和操作。
解析:
12.8.5 观察者模式案例
模拟锅炉的温度显示情况。假如被观察者代表锅炉,用TemperatureGUI表示。为了以不同的方法显示温度值,设计了几个观察者,摄氏温度图形显示界面CelsiusGUI对象、华氏温度图形显示界面FahrenheitGUI对象和凯文温度显示界面KelvinGUI对象,共同观察被观察者TemperatureGUI对象。
当用户在TemperatureGUI图形界面中输入摄氏、华氏或者凯文温度的时候,相应地,根据温度换算的情况,几个温度观察者界面将分别显示摄氏、华氏或者凯文温度,并且还显示温度颜色,即用不同的颜色表示不同的温度。使用观察者模式,进行设计。
13.5.1 高内聚低耦合表明的是什么设计思路?
答:
高内聚低耦合是软件工程中的概念,是判断设计的好坏的标准,主要是面向对象设计,主要是看类的内聚性是否高,耦合度是否低。
13.5.2 什么是高内聚度?
答:
高内聚度是对一个类中的各个职责之间相关程度和集中程度的度量。一个具有高度相关职责的类并且这个类所完成的工作量不是特别巨大,那么它就具有高内聚度。包括两个意思:不要给一个类分派太多的职责,在履行职责时尽量将部分职责分派给有能力完成的其他类去做。不相关的职责不要分派给同一个类。
系统:系统是由为了达到特定目的的而组织起来的模型元素构成,可用从不同抽象层次和不同角度建造的模型来描述它。
子系统:如果一个系统比较复杂,可把它分解成一组子系统,每个子系统要完成特定的功能,有自己的应用环境,通过接口与系统的其他子系统交互。
划分子系统:对一个大而复杂的系统,要把它分解成若干较小的子系统,在对每一个子系统进行求解,最后把这些子系统集成为系统。
分解系统考虑的因素:
14.2.1 模型的含义
14.2.2 模型与视图
状态 | 设计视图 | 进程视图 | 实现视图 | 部署视图 | 用况视图 |
---|---|---|---|---|---|
静态 | 类图、对象图、结构图 | 类图、对象图、结构图 | 构件图、组合结构图 | 部署图 | 用况图 |
动态 | 交互图、状态图、活动图 | 交互图、状态图、活动图(更加注重进程和线程) | 交互图、状态图、活动图 | 交互图、状态图、活动图 | 交互图、状态图、活动图 |
14.2.3 模型的抽象层次
14.2.4 模型间的一致性检查
14.3.1 说明视图、模型及系统之间的关系。
答:
对客观现实的事物进行抽象和刻画所得到的结果,称为模型。将部分模型数据以可视化、便于理解的形式呈现出来就是视图。模型是为了更好地理解所要建造的系统,通过对现实世界的简化而构造的系统语义抽象。