第1章 软件设计模式础
1.1 软件设计模式概述
1.2 UML中的类图
1.3 面向对象的设计原则
- 名词解释
- 一个软件实体应当对扩展开放,对修改关闭,即在不修改源代码的基础上扩展一个系统的行为。
- 一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。
- 在软件中如果能够使用基类对象,那么一定能够使用其子类对象。
- 是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结,使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。
- 单项选择择题
- ( A ) 2.〔 A 〕 3. ( A ) 4. ( D ) 5. ( D )
6.( A ) 7. ( D ) 8.〔 D 〕 9.〔 D 〕 10.〔 E 〕
11.( C ) 12.〔 C 〕 13. ( A )
- 多项选择择题
1.( A、B、C、D ) 2. ( A、B ) 3.( A、D ) 4.( A、B、C、D )
- 填空题
1.依赖倒转、迪米特法则、单一职责
2.模式名字 、 目的 、 问题 、 解决方案 、效果、 实例代码
3.超类、子类
4.开闭
5.用户
6.依赖倒转
7.组合/聚合
8.结构型 、 行为型
- 依赖倒转
- 开闭
- 需求收集是否正确、体系结构的构建是否合理、测试是否完全
12.人与人之间的交流
13.接口
14.名称、 目的 、 解决方案
15.对象组合 、 类继承
16.对象组合
17.对象组合 、 类继承
18.抽象类的指针
五、 简答题
1.答:设计模式按类型分为以下三类:
-
- 创建型设计模式:以灵活的方式创建对象集合,用于管理对象的创建。
- 结构型设计模式:将己有的代码集成到新的面向对象设计中,用于处理类或对象的组合。
- 行为型设计模式:用于描述对类或对象怎样交互和怎样分配职责。
2.答: 设计模式的主要优点如下:
-
- 设计模式融合了众多专家的经验,并以一种标准的形式供广阔开发人员所用,它提供了一套通用的设计词汇和一种通用的语言以方便开发人员之间沟通和交流,使得设计方案更加通俗易懂。
- 设计模式使人们可以更加简单方便地复用成功的设计和体系结构,将已证实的技术表述成设计模式也会使新系统开发者更加容易理解其设计思路。设计模式使得重用成功的设计更加容易,并防止那些导致不可重用的设计方案。
- 设计模式使得设计方案更加灵活,且易于修改。
- 设计模式的使用将提高软件系统的开发效率和软件质量,且在一定程度上节约设计成本。
- 设计模式有助于初学者更深入地理解面向对象思想,一方面可以帮助初学者更加方便地阅读和学习现有类库与其他系统中的源代码,另一方面还可以提高软件的设计水平和代码质量。
-
- 答:设计模式一般有如下几个基本要素:模式名称、问题、目的、解决方案、效果、实例代码和相关设计模式,其中的关键元素包括模式名称、问题、解决方案和效果。
-
- 答:正确使用设计模式具有以下优点:
-
- 可以提高程序员的思维能力、编程能力和设计能力。
- 使程序设计更加标准化、代码编制更加工程化,使软件开发效率大大提高,从而缩短软件的开发周期。
- 使设计的代码可重用性高、可读性强、可靠性高、灵活性好、可维护性强。
-
- 答:根据类与类之间的耦合度从弱到强排列,UML中的类图有以下几种关系:依赖关系、关联关系、聚合关系、组合关系、泛化关系和实现关系。其中泛化和实现的耦合度相等,它们是最强的。
-
- 答:1〕开闭原则〔OCP〕:它要求软件实体应当对扩展开放,对修改关闭;
-
- 里氏替换原则〔LSP〕:它要求继承必须确保超类所拥有的性质在子类中仍然成立;
- 依赖倒置原则〔DIP〕:它要求软件设计要面向接口编程,不要面向实现编程;
- 单一职责原则〔SRP〕:它要求对象不应该承担太多职责,一个类应该有且仅有一个引起它变化的原因;
- 接口隔离原则〔ISP〕:它要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口,让接口中只包含客户感兴趣的方法;
- 迪米特法则〔LoD〕:它要求如果两个软件实体无须直接通信,就不应当直接相互调用,而通过第三方转发该调用;
- 合成复用原则〔CRP〕:它要求在软件复用时,要尽量先使用组合或者聚合等关联关系来实现,其次才考虑使用继承关系来实现。
第2章 创建型模式〔上〕
2.2 单例模式
2.3 原型模式
- 单项选择择题
1.〔 A 〕 2.〔 B 〕 3. ( A ) 4. ( D ) 5. ( C )
6.( B ) 7. ( B )
- 多项选择择题
1.〔 C 〕 2. ( A,B ) 3.〔 A、B 〕 4. ( A、B、C )
5.〔 A、C 〕 6.( A、B、C、D ) 7.( A,B,C,D )
- 填空题
1.对象的创建、使用别离、耦合度
2.创建型
3.创建性
4.懒汉式单例 、 饿汉式单例
5. 抽象原型类 、 具体原型类
- 程序分析题解:此题使用了单例模式,参考类图如下所示:
- 简答题
1. 答:创建型模式分为以下几种:
-
-
- 单例〔Singleton〕模式:某个类只能生成一个实例,该类提供了一个全局访问点供外部获取该实例,其拓展是有限多例模式。
- 原型〔Prototype〕模式:将一个对象作为原型,通过对其进行复制而克隆出多个和原型类似的新实例。
- 工厂方法〔Factory Method〕模式:定义一个用于创建产品的接口,由子类决定生产什么产品。
- 抽象工厂〔Abstract Factory〕模式:提供一个创建产品族的接口,其每个子类可以生产一系列相关的产品。
- 建造者〔Builder〕模式:将一个复杂对象分解成多个相对简单的部分,然后根据不同需要分别创建它们,最后构建成该复杂对象。
-
2.答:单例模式重点在于在整个系统上共享一些创建时较耗资源的对象。整个应用中只维护一个特定类实例,它被所有组件共同使用。是单例模式的经典例子。从Java 5开始你可以使用枚举〔enum〕来实现线程安全的单例。
-
-
- 答:单例〔Singleton〕模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。
-
特点:1〕单例类只有一个实例对象;2〕该单例对象必须由单例类自行创建;3〕单例类对外提供一个访问该单例的全局访问点。
应用场景:1〕在某类只要求生成一个对象的时候;2〕当对象需要被共享的场合;3〕当某类需要频繁实例化,而创建的对象又频繁被销毁的时候。
-
-
- 答:原型模式通常适用以下场景:1〕对象之间相同或相似,即只是个别的几个属性不同的时候;2〕对象的创建过程比较麻烦,但克隆比较简单时候。
-
原型模式可扩展为:带原型管理器的原型模式,它在原型模式的基础上增加了一个原型管理器PrototypeManager类。
第3章 创建型模式〔下〕
-
- 工厂方法模式
- 抽象工厂模式
- 建造者模式
- 单项选择择题
- ( B ) 2. ( A ) 3. ( C ) 4.〔 C 〕 5. ( D )
6. ( C ) 7. ( B ) 8. ( A ) 9.〔 A 〕 10.〔 A 〕
- 多项选择择题
1.( A、B、C、D ) 2.( A、B、C、D ) 3.〔 A、C 〕
- 填空题
1.工厂方法 、 抽象工厂
-
- 简单工厂
- 抽象工厂(Abstract Factory) 、 具体工厂(Concrete Factory) 、抽象产品
(Product)
-
- 工厂方法、多个等级的产品
- 抽象建造者〔Builder〕、具体建造者〔ConcreteBuilder〕、指挥者〔Director〕
五、简答题
1.答:工厂模式的最大好处是增加了创建对象时的封装层次。如果你使用工厂来创建对象,之后你可以使用更高级和更高性能的实现来替换原始的产品实现或类,这不需要在调用层做任何修改。应用场合是常常有新的对象类型要被添加进来,但你所关心的仅仅是方法的接口,不关心其实现细节,本书中已经详细地介绍了其好处和应用环境。
2.答:工厂方法模式的主要优点有:1〕用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程;2〕在系统增加新的产品时只需要添加具体产品类和对应的具体工厂类,无需对原工厂进行任何修改,满足开闭原则。
其缺点是:每增加一个产品就要增加一个具体产品类和一个对应的具体工厂类,这增加了系统的复杂度。
3.答:工厂方法模式中考虑的是一类产品的生厂,如:电视机工厂;而抽象工厂模式考虑多类产品的生产,如:电器工厂。
工厂方法模式通常适用以下场景:1〕客户只知道创建产品的工厂名,而不知道具体的产品名。如:TCL 电视工厂、海信电视工厂等;2〕创建对象的任务由多个具体子工厂中的某一个完成,而抽象工厂只提供创建产品的接口。3〕客户不关心创建产品的细节,只关心产品的品牌。
抽象工厂模式通常适用以下场景: 1〕当需要创建的对象是一系列相互关联或相互依赖的产品族时,如:电器工厂中的电视机、洗衣机、空调等;2〕系统中有多个产品族,但每次只使用其中的某一族产品。如:有的粉丝只喜欢穿李宁牌的衣、裤和鞋;3〕系统中提供
了产品的类库,且所有产品的接口相同,客户端不依赖产品实例的创建细节和内部结构。
4.答:产品的种类称为产品等级,而一个具体工厂所生产的位于不同等级的一组产品称为一个产品族。
5.答:建造者模式的定义: 指将一个复杂对象的构造与它的表示别离,使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。
该模式的主要优点是: 1〕各个具体的建造者相互独立的,有利于系统的扩展;2〕客户端不必知道产品内部组成的细节,便于控制细节风险。
其缺点是:1〕产品的组成部分必须相同,这限制了其使用范围;2〕如果产品的内部变化复杂,该模式会增加很多的建造者类。
建造者模式通常在以下场合使用: 1〕创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的;2〕创建复杂对象的算法独立于该对象的
组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。
六、编程题
说明:1-5编程题可参考本章节的实例自己实现。
第4章 结构型模式〔上〕
4.2 代理模式
4.3 适配器模式
4.4 桥接模式
- 单项选择择题
- ( A ) 2.〔 A 〕 3. ( D ) 4. ( B ) 5. ( A )
6. ( C ) 7. ( D )
- 多项选择择题
1.〔 A、D 〕 2. ( A、B、D ) 3.〔 A、C、D 〕 4. ( A、B、C )
- 填空题
- 适配器〔Adapter〕模式 、桥接(Bridge)模式、装饰(Decorator)模式、外观(Facade) 模式 、享元(Flyweight)模式
- 真实主题〔RealSubject〕类 、 代理〔Proxy〕类
- 动态代理模式
4.继承 、 组合/聚合
5. 适配者〔Adaptee〕类 、 适配器〔Adapter〕类
6.桥接
7. 适配器
- 程序分析题
解:1〕此题使用了代理器模式; 2〕其参考结构图如下所示:
五、简答题
-
- 答: 代理〔Proxy〕模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。
代理模式有以下的应用场景:1〕为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问时;2〕要创建的目标对象开销很大时;3〕控制不同种类客户对真实对象的访问权限时;4〕当调用目标对象需要附加一些额外的处理功能时;5〕为了提高系统的性能,需延迟对目标的加载时。
-
- 答:代理模式的主要优点有:1〕代理模式在客户端与目标对象之间起到一个中介作用和保护目标对象的作用;2〕代理对象可以扩展目标对象的功能;3〕代理模式能将客户端与目标对象别离,在一定程度上降低了系统的耦合度。
其主要缺点是:1〕在客户端和目标对象增加一个代理对象,会造成请求处理速度变慢; 2〕增加了系统的复杂度。
-
- 答:远程代理:这种方式通常是为了隐藏目标对象存在于不同地址空间的事实,方便客户端访问。例如用户申请某些网盘空间时,会在用户的文件系统中建立一个虚拟的硬盘,用户访问它实际访问的是网盘空间。
虚拟代理:这种方式通常用于要创建的目标对象开销很大时。比方下载一幅很大的图像需要很长时间,因某种计算比较复杂而短时间无法完成,这时可以先用小比例的虚拟代理替换真实的对象,消除用户对服务器慢的感觉。
安全代理:这种方式通常用于控制不同种类客户对真实对象的访问权限。
-
- 答:适配器模式〔Adapter〕的定义如下: 将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。适配器模式分为类结构型模式和对象结构型模式2种,前者类之间的耦合度比后者高,且要求程序员了解现有组件库中的相关组件的内部结构,所以应用相对较少些。
Java例子可参考本章节相关实例设计。
-
- 答:适配器模式通常适用以下场景: 1〕以前开发的系统存在满足新系统功能需求的类,但其接口同新系统的接口不一致;2〕使用第三方提供的组件,但组件接口定义和自己要求的接口定义不同。
应用实例可参考本章节相关实例设计。
-
- 答:桥接模式的定义如下: 将抽象与实现别离,使他们可以独立的变化。它是用组合关系代替继承关系来实现,从而降低了抽象和实现这2个可变维度的耦合度。
其优点是: 1〕由于抽象与实现别离,所以扩展能力强;2〕其实现细节对客户透明。
缺点是:由于聚合关系建立在抽象层,要求开发者针对抽象化进行设计与编程,这增加了系统的理解与设计难度。
六、综合题
1.解:此题可使用适配器模式和抽象工厂模式,参考类图如下所示: 其中:1〕PlayerFactory为抽象工厂,MediaPlayerFactory和RealPlayerFactory是具体工厂;
-
- MainWindow〔主窗口〕和PlayerList〔播放列表〕是两个抽象产品;
- MediaPlayerWindow和RealPlayerWindow是两个具体产品,是对MainWindow的实现;
- MediaPlayerList和RealPlayerList是两个具体产品,是对PlayerList的实现;
- MediaPlayerWindow和MediaPlayerList由MediaPlayerFactory生产;
- RealPlayerWindow和RealPlayerList由RealPlayerFactory生产;
- MediaPlayerAPI是已有的API,充当适配者,供MediaPlayerWindow〔适配器〕和 MediaPlayerList〔适配器〕调用。
- RealPlayerAPI也是已有的API,充当适配者,供RealPlayerWindow〔适配器〕和 RealPlayerList〔适配器〕调用。
第5章 结构型模式〔下〕
5.1 装饰模式
5.2 外观模式
5.3 享元模式
5.4 组合模式
- 单项选择择题
1. ( D ) 2. ( D ) 3. ( B ) 4. ( C ) 5.〔 B 〕
6.( C ) 7. ( D ) 8. ( A ) 9. ( B ) 10.( C )
- 多项选择择题
1.( A,B,C,D ) 2.〔 B,C 〕 3.〔 A、B 〕 4.( A、B、C )
5. ( A、B、C、D ) 6.( A,B ) 7. ( C,D )
- 填空题
1.抽象构件〔Component〕、具体构件〔Concrete Component〕、抽象装饰〔Decorator〕 2.迪米特 3.内部状态 、 外部状态
4.单纯 、 复合 5.结构型、创建型
6.透明式 、 安全式
四、程序分析题
- 解:此题使用了享元模式,参考类图如下所示:
- 解:1〕此题使用了享元模式。
2〕其参考程序代码如下所示: import java.util.*; public class WareFactory { private ArrayList Wares = new ArrayList(); private int totalNum=0;
public WareFactory()
{
KitchenWare nd1=new bowl("饭碗");
Wares.add(nd1);
KitchenWare nd2=new cup("杯子");
Wares.add(nd2);
}
public KitchenWare getKitchenWare(String type)
{
if(type.equalsIgnoreCase("饭碗"))
{
totalNum++;
return (KitchenWare)Wares.get(0);
}
else if(type.equalsIgnoreCase("杯子"))
{
totalNum++;
return (KitchenWare)Wares.get(1);
}
else { return null; }
}
public int getTotalWare(){ return Wares.size(); } public int gettotalNum() { return totalNum; }
} public interface KitchenWare { public String getType(); public void use();
} public class bowl implements KitchenWare { private String type;
public bowl(String type) { this.type=type; } public String getType() { return this.type; }
public void use() { System.out.println("使用的厨具是:" + this.type);}
} public class cup implements KitchenWare { private String type;
public cup(String type) { this.type=type; } public String getType() { return this.type; } public void use() { System.out.println("使用的厨具是:" +this.type); }
}
public class Client2010 {
public static void main(String[] args) {
KitchenWare kw1,kw2,kw3,kw4;
WareFactory df=new WareFactory(); kw1=df.getKitchenWare("饭碗"); kw1.use();
kw2=df.getKitchenWare("饭碗"); kw2.use();
kw3=df.getKitchenWare("杯子"); kw3.use();
kw4=df.getKitchenWare("杯子"); kw4.use();
System.out.println("厨具种类:" + df.getTotalWare());
System.out.println("生成的厨具数alNum());
}
}
五、简答题
1. 答:装饰模式增加强了单个对象的能力。Java IO 到处都使用了装饰模式,经典的例子就是Buffered系列类如BufferedReader和BufferedWriter,它们增强了Reader和
Writer对象,以实现提升性能的 Buffer 层次的读取和写入。
-
- 答:装饰模式是一种用于替代继承的技术,它使用对象之间的关联关系来取代类之间的继承关系。当不能采用继承的方式对系统进行扩展或者采用继承不利于系统扩展和维护时可以使用装饰模式。在装饰模式中引入了装饰类,在装饰类中既可以调用待装饰的原有类的方法,还可以增加新的方法,以扩充原有类的功能。这些都不用改变原有对象,满足开闭原则。
-
- 答:外观模式的定义:是一种通过为多个复杂的子系统提供一个一致的接口,而使这些子系统更加容易被访问的模式。
其主要优点有:1〕降低了子系统与客户端之间的耦合度,使得子系统的变化不会影响到调用它的客户类;2〕对客户屏蔽了子系统组件,减少了客户处理的对象数目,并使得子系统使用起来更加容易;3〕降低了大型软件系统中的编译依赖性,简化了系统在不同平台之间的移植过程,因为编译一个子系统不会影响其他的子系统,也不会影响到外观对象。
其主要缺点是:1〕不能很好地限制客户使用子系统类;2〕增加新的子系统可能需要修改外观类或客户端的源代码,违背了“开闭原则”。
其应用场景有:1〕对分层结构系统构建时,使用外观模式定义子系统中每层的入口点可以简化子系统之间的依赖关系;2〕对于一个复杂系统,其子系统很多,外观模式可以为系统设计一个简单的接口供外界访问;3〕当客户端与多个子系统之间存在很大的联系时,引入外观模式可将它们别离,从而提高子系统的独立性和可移植性。
-
- 答:享元工厂角色负责创建和管理享元角色。当客户对象请求一个享元对象时,享元工厂检查系统中是否存在符合要求的享元对象,如果存在则提供应客户;如果不存在的话,则创建一个新的享元对象,它是工厂模式在享元模式中的应用。
-
- 答:组合模式包含抽象构件〔Component〕角色、树叶构件〔Leaf〕角色、树枝构件
〔Composite〕角色。它分为透明式的组合模式和安全式的组合模式2种。安全组合模式的类图如下:
第6章 行为型模式〔上〕
6.2 模板方法模式
6.3 策略模式
6.4 命令模式
- 单项选择择题
- ( A ) 2. ( D ) 3. ( C ) 4. ( B ) 5. ( A )
6.〔 B 〕 7. ( D ) 8. ( A ) 9. ( B )
- 多项选择择题
1.〔 B,C,D 〕 2. ( A,B,D ) 3. ( A,B,C ) 4.〔 A,B,C,D 〕
- 填空题
- 行为型模式
- 模板方法
- 抽象方法 、具体方法 、 钩子方法
- 策略
- 简单工厂
- 命令
- 简答题
- 答:行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间
怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及到算法与对象间职责的分配。
共有11种行为型模式,它们的定义如下:
-
- 模板方法〔Template Method〕模式:定义一个操作中的算法骨架,而将算法的一些步骤延迟到子类中,使得子类可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
- 策略〔Strategy〕模式:定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的改变不会影响到使用算法的客户。
- 命令〔Command〕模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
- 职责链〔Chain of Responsibility〕模式:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
- 状态〔State〕模式:允许一个对象在其内部状态发生改变时改变其行为能力。
- 观察者〔Observer〕模式:多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其它多个对象,从而影响其它对象的行为。
- 中介者〔Mediator〕模式:定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解。
- 迭代器〔Iterator〕模式:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。
- 访问者〔Visitor〕模式:在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。
- 备忘录〔Memento〕模式:在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它。
- 解释器〔Interpreter〕模式:提供如何定义语言的文法,以及对语言句子的解释方法,即解释器。
-
- 答:模板方法的主要优点是:
-
- 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展;
- 它在父类中提取了公共的部分代码,便于代码复用;
- 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
模板方法的主要缺点是:
-
- 对每个不同的实现都需要定义一个子类,这会导致类的个数增加,系统更加庞大,设计也更加抽象;
- 父类中的抽象方法由子类实现,子类执行的结果会影响父类的结果,这导致一种反向的控制结构,它提高了代码阅读的难度。
其应用实例有:〔自己介绍〕
-
- 答:策略模式的结构图如下: 其应用场景有:1〕一个系统需要动态地在几种算法中选择一种时,可将每个算法封装到策略类中;2〕一个类定义了多种行为 , 并且这些行为在这个类的操作中以多个条件语句的形式出现,可将每个条件分支移入到它们各自的策略类中以代替这些条件语句;3〕系统中各算法彼此完全独立,且要求对客户隐藏具体算法的实现细节时;4〕系统要求使用算法的客户不应该知道其操作的数据时,可使用策略模式来隐藏与算法相关的数据结构;5〕多
个类只区别在表现行为不同,可以使用策略模式,在运行时动态选择具体要执行的行为。
-
- 答:接口定义了增加〔add〕、删除〔remove〕、修改〔set〕、查询
〔indexOf〕等策略,其实现类ArrayList、LinkedList等采用了不同的算法来实现这些策略,用户可根据其特点选用它们。
-
- 答:命令模式通常适用以下场景:1〕当系统需要将请求调用者与请求接收者解耦时,命令模式使得调用者和接收者不直接交互;2〕当系统需要随机请求命令或经常增加或删除命令时,命令模式比较方便实现这些功能;3〕当系统需要执行一组操作时,命令模式可以定义宏命令来实现该功能;4〕当系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作时,可以将命令对象存储起来,采用备忘录模式来实现。
其应用实例有:〔自己举例〕
-
- 答:将命令模式与前面学的组合模式联合使用,这就构成了宏命令模式,也叫组合命令模式,其具体结构图如下:
- 编程题
解:1〕此题使用了策略模式
2〕其参考程序代码如下所示:
interface TravelStrategy
{
public void travel();
}
class AirplaneStrategy implements TravelStrategy
{
public void travel()
{
System.out.println("飞机游!");
}
}
class TrainStrategy implements TravelStrategy
{ public void travel()
{
tln("火车游!");
}
}
class BicycleStrategy implements TravelStrategy
{ public void travel()
{
System.out.println("自行车游!");
} }
class Person
{ private TravelStrategy ts;
public setStrategy(TravelStrategy ts)
{ this.ts=ts;
}
public void travelMethod()
{
ts.travelMethod();
}
} class Client
{ public static void main(String args[])
{
TravelStrategy ts = new BicycleStrategy〔〕; Person p1 = new Person(); p1.setStrategy(ts);
P1.travelMethod();
}
}
第7章 行为型模式〔中〕
7.1 职责链模式
7.2 状态模式
7.3 观察者模式
7.4 中介者模式
- 单项选择择题
- ( B ) 2.〔 C 〕 3. ( D ) 4.( D ) 5.( B )
6.( C ) 7. ( D ) 8.〔 C 〕
- 多项选择择题
- ( A,B,D ) 2. ( A,C,D ) 3.〔 A、B、C 〕 4.( A,B,D ) 5.( B,C,D )
- 填空题
- 对象行为型
- 纯的职责链模式 、 不纯的职责链模式
- 环境〔Context〕、抽象状态〔State〕、 具体状态〔ConcreteState〕
- 观察者、命令
- 、
- 不定义中介者接口,把具体中介者对象实现成为单例
- 设计题
1.解:此题可使用观察者模式,参考类图如下所示:
- 简答题
- 答:职责链模式的定义:为了防止请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处理它为止。
-
- 答:职责链模式是一种对象行为型模式,其主要优点有:
-
- 降低了对象之间的耦合度。该模式使得一个对象无需知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无需拥有对方的明确信息。
- 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则;
- 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。
- 职责链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其它所有处理者的引用,这防止了使用众多的if或者if-else语句。
- 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。
其主要缺点是:
-
- 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理;
- 对于比较长的职责链,请求的处理可能涉及到多个处理对象,系统性能将受到一定影响;
- 职责链建立的合理性要靠客户端来保证,增加了程序的复杂性,可能会由于职责链的错误设置而导致系统出错,如:可能会造成循环调用。
-
- 答:通常在以下情况下可以考虑使用状态模式:1〕当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式;2〕一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态时。
在有些情况下,可能有多个环境对象需要共享一组状态,这时需要引入享元模式,将这些具体状态对象放在集合中供程序共享,这就是共享状态模式。
-
- 答:观察者模式又叫做发布-订阅〔Publish/Subscribe〕模式、模型-视图〔Model/View〕模式、源-监听器〔Source/Listener〕模式或从属者〔Dependents〕模式。
-
- 答:观察者模式是基于目标对象的状态发生变化,而促使观察者对象作出相应操作的一种行为型模式。如,一个天气系统,当天气变化时,展示给公众的视图中会有所反映,这里的天气是目标,而视图是观察者。
-
- 答:中介者模式包含:抽象中介者〔Mediator〕角色、具体中介者〔ConcreteMediator〕角色、抽象同事类〔Colleague〕角色、具体同事类〔ConcreteColleague〕角色。
其结构图如下:
- 综合题
1.解:对于描述1)可以选择使用工厂方法模式,对于描述2)可以选择使用观察者模式,参考类图如下所示:
在类图中,HouseCreator是抽象房屋工厂类,其子类VilladomCreator用于创建别墅 Villadom,子类ApartmentCreator用于创建公寓Apartment,Villadom和Apartment都是抽象房屋类House的子类,此时应用了工厂方法模式,如果增加新类型的房屋,只需对应增加新的房屋工厂类即可,原有代码无须做任何修改;House类同时作为抽象观察目标,子类 Villadom和Apartment作为具体观察目标,相关人员类Stakeholder作为抽象观察者,其子类Manager〔主管〕作为具体观察者,实现了在Stakeholder中声明的response()方法,当房屋售出时,房屋的状态status将发生变化,在setStatus()方法中调用观察者的 response()方法,即主管将收到相应消息,此时应用了观察者模式。
2.解:对于描述1)可以选择使用中介者模式,对于描述2)可以选择使用适配器模式,参考类图如下所示:
在类图中,各类的角色如下:
- 旅游公司:抽象中介者;
- 广之旅:具体中介者;
- 大学生:抽象同事类;
- 韶关学院学生:是具体同事类,也是目标抽象类;
- 哈佛大学生、墨尔本大学生:是具体同事类,也是适配者类;
- 翻译1、翻译2:适配器类。
3.解:1〕要完成以上功能,需使用“职责链模式”和“代理模式”;
-
-
- 其参考类图如下所示:
-
-
-
- 在以上类图中,用到了2种模式: a〕职责链模式,其中“学校类”是抽象处理者,“初级学校类、中级学校类、高级学校类”是具体处理者,“学员类”是请求类; b〕代理模式,其中“服务器类”是抽象主题类,“代理服务器类”是代理主题类, “远程服务器类”是真实主题类,“学员类”是客户类。
-
第8章 行为型模式〔下〕
-
- 迭代器模式
- 访问者模式
- 备忘录模式
- 解释器模式
- 单项选择择题
- ( C ) 2.( B ) 3.〔 C 〕 4. ( B )
- 多项选择择题
- ( C ) 2. ( A,B,C,D ) 3. ( A,B,C,D )
- 简答题
- 答:迭代器模式主要包含以下角色:⑴ 抽象聚合〔Aggregate〕角色;⑵ 具体聚合
〔ConcreteAggregate〕角色;⑶ 抽象迭代器〔Iterator〕角色;⑷ 具体迭代器
〔ConcreteIterator〕角色。其结构图如下:
-
- 答:访问者〔Visitor〕模式的定义:将作用于某种数据结构中的各元素的操作别离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提供多种访问方式。
其主要优点有:1〕扩展性好。能够在不修改对象结构中的元素的情况下,为对象结构中的元素添加新的功能;2〕复用性好。可以通过访问者来定义整个对象结构通用的功能,从而提高系统的复用程度;3〕灵活性好。访问者模式将数据结构与作用于结构上的操作解耦,使得操作集合可相对自由地演化而不影响系统的数据结构;4〕符合单一职责原则。
其主要缺点是:1〕增加新的元素类很困难。在访问者模式中,每增加一个新的元素类,都要在每一个具体访问者类中增加相应的具体操作,这违背了“开闭原则”;2〕破坏封装。访问者模式中具体元素对访问者公布细节,这破坏了对象的封装性;3〕违反了依赖倒置原则。访问者模式依赖了具体类,而没有依赖抽象类。
-
- 答:忘录模式的应用场景如下:
-
- 需要保存与恢复数据的场景,如:玩游戏时的中间结果的存档功能。
- 需要提供一个可回滚操作的场景,如:Word、记事本、Photoshop、Eclipse 等软件在编辑时按“Ctrl+Z”键,还有数据库中事务操作。
-
- 答:1〕文法:是用于描述语言的语法结构的形式规则。2〕句子:是语言的基本单位,是语言集中的一个元素,它由终结符构成,能由“文法”推导出。3〕语法树:是句子结构的一种树型表示,它代表了句子的推导结果,它有利于理解句子语法结构的层次。
-
- 答:Jep是Java expression parser的简称,即java表达式分析器,它是一个用来转换和计算数学表达式的java库。通过这个程序库,用户可以以字符串的形式输入一个任意的公式,然后快速地计算出其结果。
使用前先从 或其它网站下载 Jep包,解压该ZIP包后,将文件移到你选择的目录中,在Eclipse的“Java 构建路径”对话框的“库”选项卡中选择“添加外部 JAR(X)...”,将该 Jep包添加到你的项目中后即可设计相关类来使用其中的类库。
-
- 答:1〕装饰器设计模式〔Decorator design pattern〕被用于多个Java IO类中; 2〕单例模式〔Singleton pattern〕用于Runtime、Calendar和其他的一些类中;3〕工厂模式〔Factory pattern〕被用于各种不可变的类如Boolean,像;4〕观察者模式〔Observer pattern〕被用于Swing 和很多的事件监听中。
- 编程题
1.解:1〕此题使用了迭代器模式 2〕其参考程序代码如下所示:
interface Aggregate { Iterator createIterator(); } interface Iterator
{ void first(); void next(); boolean hasNext();
Object currentItem();
} class ConcreteAggregate implements Aggregate
{ private Object[] obj={"筷","杯","锅”,"碗","瓢","盆"}; public Iterator createIterator() { return new ConcreteIterator(); } private class ConcreteIterator implements Iterator
{ private int currentIndex=0; public void first() { currentIndex=0; }
public void next() { if(currentIndex<obj.length){ currentIndex++; }} public boolean hasNext(){ return currentIndex<obj.length; } public Object currentItem(){ return obj[currentIndex]; }
}
} class Client
{
public static void process(Aggregate a)
{
Iterator i=a.createIterator(); while(i.hasNext())
{
System.out.println(i.currentItem().toString());
i.next();
}
}
public static void main(String a[])
{
Aggregate a=new ConcreteAggregate(); process(a);
}
}
2. 解:参考本章节的例来实现该实例。
更多推荐
软件设计模式〔Java版〕习题
发布评论