一.填空题(30)
1.行为型模式分为类行为型模式和对象行为型模式两种。第一种行为型模式使用继承关系在几个类之间分配行为,第二种行为型模式使用对象的聚合关联关系分配行为;根据合成复用原则,系统中要尽量使用关联关系取代继承关系。因此,大部分行为型设计模式都属于对象行为型模式。
2.创建型模式对对象的实例化过程进行了抽象,能够将软件模块中对象的创建和对象的使用进行了分离,为了使软件的结构更加清晰,外界对这些对象只需要知道其公共接口,而不需要清楚其具体的实现细节,使整个系统的设计更加符合单一职责原则。
3.观察者模式描述了如何建立对象与对象之间的依赖关系,如何构造满足这种需求的系统。这一模式的关键对象是观察目标和观察者,一个目标可以有任意数目的与之相依赖的观察者,一旦目标的状态发生改变,所有的观察者都将得到通知。作为对这个通知的响应,每个观察者都将及时更新自己的状态,以与目标同步。这种交互也称为发布-订阅(Publish/Subscribe),目标是通知的发布者,它发布通知时并不需要知道谁是它的观察者,可以有任意数目的观察者订阅并接收通知。
4.在一个纯的职责链模式里面,一个请求必须被某一个处理者对象所接收,在一个不纯的职责链模式里面,一个请求可以最终不被任何接收端对象所接受。
5.中介者模式的优点是:简化了对象之间的交互,将各同事解耦,减少子类生成,可以简化各同事类的设计和实现。
6.行为型模式包括:职责链模式(Responsibility),命令模式(Command),解释器模式(Interpreter),迭代器模式(Interator),中介者模式(Mediator),备忘录模式(Mementor),观察者模式(Obsetver),状态模式(State),策略模式(Strategy),模板方法模式(Template Methood),访问者模式(Visitor)。
二.简答题(30)
1.请叙述设计模式的定义,基本要素和关键要素。
定义:设计模式是一套被反复使用、多数人知晓的、经过分类编目的代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被人理解、保证代码可靠性;
设计模式一般有如下几个要素:模式名称、问题、目的、解决方案、效果、实例代码和相关设计模式;
其中,关键要素包括以下四个方面:模式名称、问题解决方案和效果。
2.请解释纯和不纯职责链。
一个纯的职责链模式,要求一个具体处理者对象只能在两个行为中选择一个:一个是承担责任、另一个是把责任推给下家,不允许出现某一个具体处理者对象,在承担了一部分责任后,又将责任像下传的情况,在一个纯的职责链模式里面,一个请求必须被某一个处理者对象所接受,在一个不纯的职责链模式里面,一个请求可以最终不被任何接受端对象所接受。适合3.列举三个以上适合职责链模式的情况。
职责链模式的情况有:
(1)有多个对象可以处理同一个请求,具体哪个对象处理该请求,由运行时刻自动决定;
(2)在不明确指定接受者的情况下,向多个对象中的一个提交一个请求;
(3)可动态指定一组对象处理请求。
4.简述简单工厂模式的优点。
(1)实现了对责任的分割,它提供了专门的工厂类用于创建对象。
(2)客户端无须知道所创建的具体产品类的类名,只需要知道具体产品类所对应的参数即可,对于一些复杂的类名,通过简单工厂模式可以减少使用者的记忆量。
(3)通过引入配置文件,可以在不修改任何客户端代码的情况下更换和增加新的具体产品类。
5.解释观察者模式的动机。
建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在此,发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展,这就是观察者模式的模式动机。
6.解释享元模式的定义和优点。
定义:运用共享技术有效地支持大量细粒度对象的复用。系统只使用少量的对象,而这些对象都很相似,状态变化很小,可以实现对象的多次复用。由于享元模式要求能够共享的对象必须是细粒度对象,因此它又称为轻量级模式,它是一种对象结构型模式。
优点:
(1)它可以极大减少内存中对象的数量,使得相同对象或相似对象在内存中只保存一份。
(2)享元模式的外部状态相对独立,而且不会影响其内部状态,从而使得享元对象可以在不同的环境中被共享。
三.综合题(17)
1.常用的面向对象设计原则包括七个,这些原则不是孤立存在的,它们相互依赖、相互补充,请用表格表示该七个原则的内涵,并说明其重要性。
2.根据创建型模式、结构型模式、行为型模式、类模式和对象型模式将常用的二十种以上模式进行分类。
四.创作题(10)
1请自选一种模式解释:某OA系统需要提供一个假条审批的模块,如果员工请假天数少于3天,主任可以审批该假条;如果员工请假天数大于3天小于10天经理可以审批;如果员工请假天数大于10天小于30天,总经理可以审批;如果超过30天,总经理也不能审批,提示相应的拒绝信息。
五.设计模式结构题(13)
1.请给出产品族和等级的完整结构。
2.完成以下产品族和产品结构。
3.完成克隆结构。
4.根据代理模式完成以下结构。
5.根据提示完成观察者结构实例。
6.利用中介者模式将下述系统变换为理想中介模式。
第二篇:设计模式复习笔记
设计模式复习
选择题填空题简答题程序题
第一章 概念复用机制 1.6、1.7、1.8
第二章 文档结构 2.2、2.4、2.6
第三章 3.1、3.3、3.5
第四章 4.1、4.2、4.5、4.6
第五章 5.1、5.2、5.7、5.10
问题以及解决问题的方法,效果、优缺点
第一章 引言
设计模式:是对被用来在特定场景下解决一般设计问题的类和相互通信的对象的描述。 模式的四个基本要素:模式名称、问题、解决方案、效果。
1.6 设计模式怎样解决设计问题
1.6.1 寻找合适的对象
面向对象程序由对象组成,对象包括数据和对数据进行操作的过程,过程通常称为方法或操作。对象在收到客户的请求(或消息)后,执行相应的操作。
客户请求是使对象执行操作的唯一方法,操作又是对象改变内部数据的唯一方法。
1.6.2 决定对象的粒度
1.6.3 指定对象的接口
对象声明的每一个操作指定操作名、作为参数的对象和返回值,这就是所谓的操作的型构。
对象操作所定义的所有操作型构的集合被称为该对象的接口。
类型是用来标识特定接口的一个名字。
1.6.4 描述对象的实现
抽象类的主要目的是为它的子类定义公共接口。一个抽象类将把它的部分或全部操作的实现延迟到子类中,因此,一个抽象类不能被实例化。
针对接口编程,而不是针对实现编程
1.6.5 运用复用机制
面向对象系统中功能复用的两种最常用技术是类继承和对象组合
优先使用对象组合,而不是类继承
委托是一种组合方法,它使组合具有与继承同样的复用能力。在委托方式下,有两个对象参与处理一个请求,接受请求的对象将操作委托给它的代理者。
1.6.6 关联运行时刻和编译时刻的结构
集合意味着一个对象拥有另一个对象或对另一个对象负责。一般我们称一个对象包含另一个对象或者是另一个对象的一部分。聚合意味着聚合对象和其所有者具有相同的声明周期。
相识意味着一个对象仅仅知道另一个对象,有时相识也被称为“关联”或“引用”关系。相识是一种比聚合要弱的关系,它只标识了对象较松散的耦合关系。
1.6.7 设计应支持变化
导致重新设计的一般原因,以及解决这些问题的设计模式:
(1)通过显式地指定一个类来创建对象
设计模式:Abstract Factory、Factory Method、Prototype
(2)对特殊操作的依赖
设计模式: 、Command
(3)对硬件和软件平台的依赖
设计模式:Abstract Factory、Bridge
(4)对对象表示或实现的依赖
设计模式:Abstract Factory、Bridge、Memento、Proxy
(5)算法依赖
设计模式:Builder、Iterator、Strategy、Template、Method
(6)紧耦合
设计模式:Abstract Factory、Command、Fa?ade、Mediator、Observer、Chain of Resposibility
(7)通过生成子类来扩充功能
设计模式:Bridge、Chain of Resposibility、Composite、Decorator、Observer、Strategy
(8)不能方便地对类进行修改
设计模式:Adapter、Decorator、Visitor
1.7 怎样选择设计模式
考虑设计模式是怎样解决设计问题的
浏览模式的意图部分
研究模式怎样互相关联
研究目的相似的模式
检查重新设计的原因
考虑你的设计中哪些是可变的
1.8怎样使用设计模式
大致浏览一遍模式
回头研究结构部分、参与者部分和协作部分
看代码示例部分,看看这个模式代码形式的具体例子
选择模式参与者的名字,是它们在应用上下文中有意义
定义类
定义模式中专用于应用的操作名称
实现执行模式中责任和协作的操作
第二章 实例研究:设计一个文档编辑器
2.2文档结构
文档结构:对文档内部拜师的选择几乎影响Lexi设计的每个方面
我们将为出现在文档结构中的所有对象定义一个抽象类图元。
第三章 创建型模式
3.1 Abstract factory(抽象工厂)--对象创建型模式
意图:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 别名:Kit
适用性:
一个系统要独立于它的产品的创建、组合和表示时。
一个系统要由多个产品系列中的一个来配置时。
当你要强调一系列相关的产品对象的设计以便进行联合使用时。
当你提供一个产品类库,而只想显示它们的接口而不是实现时。
效果:优缺点
(1) 它分离了具体的类
(2) 它使得易于交换产品系列
(3) 它有利于产品的一致性
(4) 难以支持新种类的产品
实现:
(1) 将工厂作为单件
(2) 创建产品
(3) 定义可扩展的工厂
相关模式:
AbstractFactory类通常用工厂方法(Factory Method)实现,但它们也可以用Prototype实现
一个具体的工厂通常是一个单件(Singleton)
3.3Factory Method(工厂方法)--对象创建型模式
意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
别名:虚构造器
适用性:
当一个类不知道它所必须创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
但当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
效果:
工厂方法不再将与特定应用有关的类绑定到你的代码中。
工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creator子类。
为子类提供挂钩
连接平行的类层次
3.5 Singleton(单件)--对象创建型模式
意图:保证一个类仅有一个实例,并提供一个访问它的全局访问点
效果:
对唯一实例的受控访问
缩小名空间
允许对操作和表示的精化、
允许可变数目的实例
比类操作更灵活
实现:
现实问题:保证一个唯一的实例
创建singleton类的子类
相关模式:
很多模式可以使用Singleton模式实现。参见Abstract Factory、Builder和Prototype
4.1 Adapter(适配器)--类对象结构型模式
意图:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容不能一起工作的那些类可以一起工作。
别名:包装器 Wrapper
动机:
有时,为复用儿童设计的工具箱类不能够被复用的原因仅仅是因为它的接口与专业应用领域所需要的接口不匹配。
适用性:
你想使用一个已经存在的类,而它的接口不符合你的需求。
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
效果:
使用Adapter模式时需要考虑的其他一些因素:
Adapter的匹配程度
可插入的Adapter
使用双向适配器提供透明操作
实现:
使用C++实现适配器类在使用C++实现适配器类时,Adapter类应该改采用公共方式继承Target类,并且用私有方式继承Adapter类。
可插入的适配器有以下三种实现途径
使用抽象操作
使用代理对象
参数化的适配器
4.2 Bridge(桥接)--对象结构模式
意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
别名:Handle/Body
动机:
当一个抽象类可能有多个实现时,通常用继承来协调它们。
适用性:
你不希望在抽象和它的实现之间有一个固定的绑定关系。
类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。 (C++)你想对客户完全隐藏抽象的实现部分。在C++中,类的表示在类接口中是可见的。
正如在意图一节的第一个图中所示的那样,有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。
你想在多个对象间共享实现(可能使用引用计数)但同时要求客户并不知道这一点。 效果:优点:
分离接口及其实现部分
提高可扩充性
实现细节对客户透明
实现:注意问题
仅有一个Implementor在仅有一个实现的时候,没有必要创建一个Implementor类 创建正确的Implementor对象
共享Implementor对象
采用多重继承机制
相关模式:
Abstract Factory模式可以用来创建和配置一个特定的Bridge模式
Adapter模式用来帮助无关的类协同工作,它通常在系统设计完成后才会被使用。
4.5 Fa?ade(外观)---对象结构型模式
意图:为子系统中的一组接口提供一个一致的界面,Fa?ade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
动机:
将一个系统划分成为若干个子系统有利于降低系统的复杂性。
适用性:
当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。Fa?ade可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过fa?ade层
客户程序与抽象类的实现部分之间存在着很大的依赖性。引入fa?ade将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
当你需要构建一个层析结构的子系统时,使用fa?ade模式定义子系统中每层的入口点。 效果:优点
他对客户屏蔽子系统组件,因而减少了客户处理的对象的数目并使得子系统使用起来更加方便。
它实现了子系统与客户之间的送耦合关系,而子系统内部的功能组件往往是紧耦合的。 如果应用需要它并不限制他们使用子系统类。因此你可以在系统易用性和通用性之间加以选择。
实现:注意问题
降低客户-子系统之间的耦合度
公共子系统类与私有子类系统类
相关模式:
Abstract Factory模式可以与Fa?ade模式一起使用以提供一个接口,这一接口可以用来一一种子系统独立的方式创建子系统对象。
通常来讲,仅需要一个Fa?ade对象,因此Fa?ade对象通常属于Singleton模式。
4.6 Flyweight(享元)--对象结构型模式
意图:运用技术有效地支持大量细粒度的对象
动机:有些应用程序得益于在其整个设计过程中采用对象技术,但简单化的实现代价极大。
适用性:
一个应用程序使用大量的对象
完全由于使用大量的对象,造成很大的存储开销
对象的大多数状态都可变为外部状态
如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。
应用程序不依赖与对象标识。由于Flyweight对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。
效果:
使用Flyweight模式时,传输、查询和/或计算外部状态都会产生运行时的开销,尤其当flyweight原先被存储为内部状态时。然而,空间上的节省抵消了这些开销。共享的flyweight越多,空间节省也就越大。
存储节省由一下几个因素决定:
因为共享,实例总数减少的数目
对象内部状态的平均数目
外部对象时计算的还是存储的
实现:注意
删除外部状态
管理共享对象
相关模式
Flyweight模式通常和Composite模式结合起来,用共享叶节点的有向无环图实现一个逻辑上的层次结构
通常,最好用Flyweight实现State 和Strategy对象
5.1 Chain Of Responsibility(责任链)—对象行为型模式
意图:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止。
动机:
考虑一个图形用户界面中上下文有关的帮助机制。用户在界面的任一部分上点击就可以得到帮助信息,所提供的帮助依赖于点击的是界面的哪一部分以及其上下文。
适用性:
有多个的对象可以处理一个请求,哪个对象处理该请求运行时刻自动确定
你想在不明确指定接受者的情况下,向多个对象中的一个提交一个请求
可处理一个请求的对象集合应被动态指定
效果:优缺点
减低耦合度
增强了给对象指派职责的灵活性
不保证被接受
实现:问题
实现后继者链两种方法实现
(1)定义新的链接(通常在Handler中定义,但也可由ConcreteHandles来定义)
(2)使用已有的链接
链接后继者
表示请求
在Smalltalk中自动转发
相关模式:
职责链常与Composite一起使用。这种情况下,一个构件的父构件可作为它的后缀
5.2 Command(命令)--对象行为型模式
意图:将一个请求封装为一个对象,从而是你可用不同的请求对可会进行参数化;对请
求排队或记录请求日志,以及支持可撤销的操作
别名:动作(action)事务(Transaction)
动机:又是必须向某对象提交请求,但并不知道关于被请求的操作或请求的接受者的任何消息。
适用性:
抽象出待执行的动作以参数化某对象。可用过程语言中的回调函数表达这种参数化机制。 在不同的时刻指定、排列和执行请求
支持取消操作
支持修改日志,这样当系统崩溃时,这些修改可以被重新做一遍。
用构建在原语操作上的高层操作构造一个系统
效果:
Command模式将调用操作的对象与指导如何实现该操作的对象解耦
Command是头等的对象。它们可像其它的对象一样被操纵和扩展
你可将多个命令装配成一个复合命令。
增加新的Command很容易,因为这无需改变已有的类。
实现:问题
一个命令对象应达到何种智能程度
支持取消(undo)和重做(redo)
避免取消操作过程中的错误积累
使用C++模板
相关模式:
Composite模式可被用来实现宏命令
Memento模式可用来保持某个状态,命令用这一状态来取消它的效果
5.7 Observer(观察者)--对象行为型模式
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都得到通知并被自动更新。
别名:依赖,发布-订阅
动机:将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维护一致性而使各类紧密耦合,因为这样降低了它们的可重用性
适用性:
当一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用
当一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变
当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象时紧密耦合的
效果:优缺点
目标和观察者件的抽象耦合
支持广播信道
意外的更新
实现:问题
创建目标到其观察者之间的映射
观察多个目标
谁触发更新
对已删除目标的悬挂引用
在发出通知前确保目标的状态自身是一致的
避免特定于观察者的更新协议-推/拉模型
显示地指定感兴趣的改变
封装复杂的更新语义
结合目标类和观察者类
5.10 Template Method(模板方法)--类行为型模式
意图:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod使得子类可以不改变一个算法的机构即可重定义该算法的某些特定步骤
适用性:
一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现
各子类中公共的行为应该提取出来并集中到一个公共父类中以避免代码重复
控制子类扩展。模板方法旨在特定点调用“hook”操作,这样就只允许在这些点进行扩展
实现:
使用C++访问控制
尽量减少原语操作
命名约定
相关模式:
Factory Method模式常被模板方法调用。
Strategy:模板方法使用继承来改变算法的一部分