问题 问答题

阅读以下关于设计模式应用的叙述,根据要求回答问题。
[说明]
某软件公司承接了一项面向儿童的模拟游戏软件的开发任务,该游戏软件主要模拟现实世界中各种鸭子的发声特征、飞行特征和外观特征。游戏软件需要模拟的鸭子种类及其特征如表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分别用于表示抽象的飞行行为与发声行为。


[问题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)对象,除非它们不喜欢默认的行为。

单项选择题 A2型题
多项选择题