问答题 阅读以下关于设计模式应用的叙述,根据要求回答问题。
[说明]
某软件公司承接了一项面向儿童的模拟游戏软件的开发任务,该游戏软件主要模拟现实世界中各种鸭子的发声特征、飞行特征和外观特征。游戏软件需要模拟的鸭子种类及其特征如表2—13所示
表2—13鸭子种类及其特征
鸭子种类 发声特征 飞行特征 外观特征
灰鸭(MallardDuck) 发出“嘎嘎”声(Quack) 用翅膀飞行(FlyWithWings) 灰色羽毛
红头鸭(RedHeadDuck) 发出“嘎嘎”声(Quack) 用翅膀飞行(FlyWithWings) 灰色羽毛、头部红色
棉花鸭(CottonDuck) 不发声(QuackNoWay) 不能飞行(FlyNoWay) 白色
橡皮鸭(RubberDuck) 发出橡皮与空气摩擦的声音(Squeak) 不能飞行(FlyNoWay) 黑白橡皮颜色
为支持将来能够模拟更多种类鸭子的特征,该公司架构师采用某种设计模式设计的类图如图2-9所示。在图2—9中,类Duck描述了抽象的鸭子,方法fly()、quack()和display()分别表示不同种类的鸭子都具有飞行特征、发声特征和外观特征;类FlyBehavior与QuackBehavior分别用于表示抽象的飞行行为与发声行为。
问答题 [问题1]
请用350字以内的文字指出该公司架构师所采用的设计模式的具体名称、设计意图及其优缺点。
【正确答案】依题意,在图2-9中,Duck为抽象类,描述了抽象的鸭子,方法fly()、quack()和display()分别表示不同种类的鸭子都具有飞行特征、发声特征和外观特征;而类RubberDuck、MallardDuck、CottonDuck和RedHeadDuck分别描述具体的鸭子种类;类Fly Behavior与QuackBehavior为抽象类,分别用于表示抽象的飞行行为与发声行为;类Fly NoWav与Fly WithWings分别描述不能飞行的行为和用翅膀飞行的行为;类Quack、Squeak与QuackNoWay分别描述发出“嘎嘎”声的行为、发出橡皮与空气摩擦声的行为和不发声的行为。鉴于不同的鸭子种类只是在行为方面有所区别,且为支持将来能够模拟更多种类鸭子的特征,该公司架构师最有可能采用策略(Strategy)设计模式来设计如图2—9所示的模拟鸭子游戏软件。
Strategy模式定义了一组能够用来表示可能行为集合的类。这些行为可以在应用程序中使用,来修改应用程序功能。Strategy(策略)模式的设计意图是,定义一系列的算法,把它们一个个封装起来,并且使它们可相互替换,使得算法可独立于使用它的客户而变化。具体而言,该模式是一种定义一系列算法的方法,从概念上看,所有这些算法完成的都是相同的工作,只是实现不同,它可以以相同的方式调用所有的算法,减少了各种算法类与使用算法类之间的耦合。Strategy模式的一般结构如图2—13所示。
【答案解析】
问答题 [问题2]
请用400字以内的文字指出该公司架构师所采用的设计模式的适用性,以及图2-9中需要考虑哪些实现问题?
【正确答案】在以下情况中,应该使用Strategy模式。
(1)许多相关类只是在行为方面有所区别。“策略”提供了一种用多个行为中的一个行为来配置一个类的方法。
(2)需要使用一个算法的不同变体。例如,定义了一些反映不同的空间或时间权衡的算法,当这些变体实现为一个算法的类层次时,可以使用策略模式。
(3)算法使用客户端未知的数据,可使用策略模式以避免暴露复杂的、与算法相关的数据结构。
(4)一个类定义了多种行为,并且这些行为在这个类的操作中以多个条件语句的形式出现。将相关的条件分支移入它们各自的Strategy类中以代替这些条件语句。
依题意,在图2-9中,需要考虑以下一些Strategy模式实现问题。
(1)定义类Duck和类FlyBehavior(或类QuackBehavior)接口。这些接口必须使得类FlyWithwings、类FlyNoWay、类Quack、类Squeak和类QuackNoWay等能够有效地访问它所需要的类Duck中的任何数据,反之亦然。一种解决办法是让类Duck将数据放在参数中传递给类FlyBehavior(或类QuackBehavior)操作,也就是说,将数据发送给类FlyBehavior(或类QuackBehavior)。这使得类FlyBehavior(或类QuackBehavior)和类Duck解耦。但从另一个角度考虑,类Duck也可能发送一些类FlyBehavior(或类QuackBehavior)不需要的数据。
另一种解决办法是让类Duck将自身作为一个参数传递给类FlyBehavior(或类QuackBehavior),该类FlyBehavior(或类QuackBehavior)再显式地向类Duck请求数据;或者类FlyBehavior(或类QuackBehavior)可以存储对它的类Duck的一个引用,这样根本不再需要传递任何东西。这两种情况下,类FlyBehavior(或类QuackBehavior)都可以请求到它所需要的数据。但要求类Duck必须对它的数据定义一个更为精细的接口,这将使得类FlyBehavior(或类QuackBehavior)和类Duck更加紧密地耦合在一起。
(2)将类FlyBehavior(或类QuackBehavior)作为模板参数。例如,在C++中,可利用模板机制用一个Strategy来配置一个类。然而这种技术仅当下面条件满足时才可以使用:可以在编译时选择Strategy;它无须在运行时改变。在这种情况下,要被配置的类(如类Duck)被定义为以一个Strategy类作为一个参数的模板类。使用模板不再需要定义给类FlyBehavior(或类QuackBehavior)定义接口的抽象类。把类FlyBehavior(或类QuackBehavior)作为一个模板参数也使得可以将一个类FlyBehavior(或类QuackBehavior)和它的类Duck静态地绑定在一起,从而提高效率。
(3)尽量使类FlyBehavior(或类QuackBehavior)成为可选的对象。即使在不使用额外的FlyBehavior(或类OuackBehayior)对象的情况下,类Duck也还有意义,那么它还可以被简化。类Duck在访问类FlyBehavior(或类QuackBehavior)前先检查它是否存在,如果有,那么就使用它;如果没有,那么类Duck执行默认的行为。这种方法的好处是客户根本不需要处理FlyBehavior(或类QuackBehavior)对象,除非它们不喜欢默认的行为。
【答案解析】
问答题 [问题3]
设计模式在力度和抽象层次上各不相同。按设计模式的目的划分,可分为创建型、结构型和行为型3种模式;按设计模式的范围划分,可分为类设计模式和对象设计模式两种。请将下列A~J标记的设计模式填入到表2—14中的(1)~(5)空缺处。(请用A~J答题)
A.Abstract Factory模式 B.Adapter模式 C.Chain of Responsibility模式
D.Decorator模式 E.Factory Method模式 F.Flyweight模式
G.Interpreter模式 H.Iterator模式 I.Template Method模式
J.Visitor模式

表2-14设计模式空间
目 的
创建型 结构型 行为型
范 围 (1) (2)
对 象 (3) (4) (5)

【正确答案】设计模式主要用于得到简洁灵活的系统设计,GoF的书中共有23个设计模式,这些模式可以按两个准则来分类:一是按设计模式的目的划分,可分为创建型、结构型和行为型3种模式;二是按设计模式的范围划分,即根据设计模式是作用于类还是作用于对象来划分,可分为类设计模式和对象设计模式,如表2—16所示。
表2-16设计模式空间
目的
创建型 结构型 行为型
范围 Factory Method Adapter(类) Interpreter
Template Method
对象 Abstract Factory
Builder
Prototype
Singleton
Adapter(对象)
Bridge
Composite
Decorator
Facade
Flyweight
Proxy
Chain of Responsibility
Command
Iterator
Mediator
Memento
Observer
State
Strategy
Visitor
创建型模式是对对象实例化过程的抽象,它通过采用抽象类所定义的接口,封装了系统中对象如何创建及组合等信息。该模式允许在系统中创建对象,而不需要在代码中标识特定类的类型,这样用户就不需要编写大量复杂的代码来初始化对象。它是通过该类的子类来创建对象的。但是,这可能会限制在系统内创建对象的类型或数目。创建型模式主要有Factory Method(工厂方法)、Abstract Factory(抽象工厂)、Builder(构建器)、Prototype(原型)和Singleton(单独)等模式。
结构型模式主要用于如何组合已有的类和对象以获得更大的结构,一般借鉴封装、代理或继承等概念将一个或多个类或对象进行组合和封装,以提供统一的外部视图或新的功能。该模式允许在不重写代码或自定义代码的情况下创建系统,从而使系统具有增强的重复使用性和应用性能。该模式控制了应用程序大部分之间的关系,将以不同的方式影响应用程序。结构型模式主要有Adapter(适配器)、Bridge(桥接)、Composite(组成)、Decorator(装饰)、Fagade(外观)、Flyweight(享元)和Proxy(代理)等。
行为型模式主要用于对象之间的职责及其提供的服务的分配,它不仅描述对象或类的模式,还描述它们之间的通信模式,特别是描述一组对等的对象怎样相互协作以完成其中任意一个对象都无法单独完成的任务。该模式可以影响一个系统的状态和行为流。通过优化状态和行为流转换及修改的方式,可以简化、优化并且提高应用程序的可维护性。行为型模式主要有Interpreter(解释器)、TemplateMethod(模板方法)、Chain of Responsibility(职责链)、Command(命令)、Iterator(迭代器)、Mediator(中介者)、Memento(备忘录)、Observer(观察者)、State(状态)、Strategy(策略)和Visitor(访问者)等。
【答案解析】