软件设计师试题分析与解答
试题1
当不适合采用生成子类的方法对已有的类进行扩充时,可以采用__(1)__设计模式动态地给一个对象添加一些额外的职责;当应用程序由于使用大量的对象,造成很大的存储开销时,可以采用__(2)__设计模式运用共享技术来有效地支持大量细粒度的对象;当想使用一个已经存在的类,但其接口不符合需求时,可以采用__(3)__设计模式将该类的接口转换成我们希望的接口。
(1)A.命令(Command)B.适配器(Adapter)
C.装饰(Decorate)D.享元(Flyweight)
(2)A.命令(Command)B.适配器(Adapter)
C.装饰(Decorate)D.享元(Flyweight)
(3)A.命令(Command)B.适配器(Adapter)
C.装饰(Decorate)D.享元(Flyweight)
试题2
__(4)__设计模式允许一个对象在其状态改变时,通知依赖它的所有对象。该设计模式的类图如下图,其中,__(5)__在其状态发生改变时,向它的各个观察者发出通知。

图15-28 设计模式UML类图
(4)A.命令(Command)B.责任链(Chain of Responsibility)
C.观察者(Observer)D.迭代器(Iterator)
(5)A.Subject B.ConcreteSubject
C.Observer D.ConcreteObserver
试题3
下面给出了4种设计模式的作用。
外观(Facade):为子系统中的一组功能调用提供一个一致的接口,这个接口使得这个子系统更加容易使用;
装饰(Decorate):当不能采用生成子类的方法进行扩充时,动态地给一个对象添加一些额外的功能;
单件(Singleton):保证一个类仅有一个实例,并提供一个访问它的全局访问点;
模板方法(Template Method):在方法中定义算法的框架,而将算法中的一些操作步骤延迟到子类中实现。
请根据下面叙述的场景选用适当的设计模式。若某面向对象系统中的某些类有且只有一个实例,那么采用__(6)__设计模式能够有效达到该目的;该系统中的某子模块需要为其他模块提供访问不同数据库系统(Oracle、SQL Server、DB2 UDB等)的功能,这些数据库系统提供的访问接口有一定的差异,但访问过程却都是相同的。例如,先连接数据库,再打开数据库,最后对数据进行查询,__(7)__设计模式可抽象出相同的数据库访问过程;系统中的文本显示类(TextView)和图片显示类(PictureView)都继承了组件类(Component),分别显示文本和图片内容。现需要构造带有滚动条,或者带有黑色边框,或者既有滚动条又有黑色边框的文本显示控件和图片显示控件,但希望最多只增加三个类,__(8)__设计模式可以实现该目的。
(6)A.外观 B.装饰 C.单件 D.模板方法
(7)A.外观 B.装饰 C.单件 D.模板方法
(8)A.外观 B.装饰 C.单件 D.模板方法
试题4
设计模式__(9)__将抽象部分与其实现部分相分离,使它们都可以独立地变化。图15-29为该设计模式的类图,其中,__(10)__用于定义实现部分的接口。

图15-29 设计模式UML类图
(9)A.Bridge(桥接)B.Composite(组合)
C.Facade(外观)D.Singleton(单例)
(10)A.Abstraction B.ConcreteImplementorA
C.ConcreteImplementorB D.Implementor
试题5
以下关于Singleton(单例)模式的描述中,正确的是__(11)__。
(11)A.它描述了只有一个方法的类的集合
B.它描述了只有一个属性的类的集合
C.它能够保证一个类的方法只能被一个唯一的类调用
D.它能够保证一个类只产生唯一的一个实例
试题6
在“模型-视图-控制器”(MVC)模式中,__(12)__主要表现用户界面,__(13)__用来描述核心业务逻辑。
(12)A.视图 B.模型 C.控制器 D.视图和控制器
(13)A.视图 B.模型 C.控制器 D.视图和控制器
试题7
在面向对象软件开发过程中,采用设计模式__(14)__。
(14)A.允许在非面向对象程序设计语言中使用面向对象的概念
B.以复用成功的设计和体系结构
C.以减少设计过程创建的类的个数
D.以保证程序的运行速度达到最优值
试题8
阅读下列说明和C++代码,将应填入(n)处的字句写在答题纸的对应栏内。
【说明】
某咖啡店当卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如表15-2所示。
表15-2咖啡及配料表

现采用装饰器(Decorator)模式来实现计算费用的功能,得到如图15-30所示的类图

图15-30类图
【C++代码】
#include
#include
using namespace std;
const int ESPRESSO_PRICE = 25;
const int DRAKROAST_PRICE = 20;
const int MOCHA_PRICE = 10;
const int WHIP_PRICE = 8;
class Beverage { //饮料
(1):string description;
public:
(2) ( ){ return description; }
(3) ;
};
class CondimentDecorator : public Beverage { //配料
protected:
(4) ;
};
class Espresso : public Beverage { //蒸馏咖啡
public:
Espresso ( ) {description="Espresso"; }
int cost ( ){return ESPRESSO_PRICE; }
};
class DarkRoast : public Beverage { //深度烘焙咖啡
public:
DarkRoast( ){ description = "DardRoast"; }
int cost( ){ return DRAKROAST_PRICE; }
};
class Mocha : public CondimentDecorator { //摩卡
public:
Mocha(Beverage*beverage){ this->beverage=beverage; }
string getDescription( ){ return beverage->getDescription( )+",Mocha"; }
int cost( ){ return MOCHA_PRICE+beverage->cost( ); }
};
class Whip :public CondimentDecorator { //奶泡
public:
Whip(Beverage*beverage) { this->beverage=beverage; }
string getDescription( ) {return beverage->getDescription( )+",Whip"; }
int cost( ) { return WHIP_PRICE+beverage->cost( ); }
};
int main() {
Beverage* beverage = new DarkRoast( );
beverage=new Mocha( (5));
beverage=new Whip((6));
cout<
return 0;
}
编译运行上述程序,其输出结果为:
DarkRoast, Mocha, Whip ¥38
试题9
阅读下列说明和Java代码,将应填入(n)处的字句写在答题纸的对应栏内。
【说明】
某咖啡店当卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如表15-3所示。
表15-3咖啡及配料表

现采用装饰器(Decorator)模式来实现计算费用的功能,得到如图15-31所示的类图

图15-31类图
【Java代码】
import java.util.*;
(1) class Beverage { //饮料
String description = "Unknown Beverage";
public (2)(){return description;}
public (3) ;
}
abstract class CondimentDecorator extends Beverage { //配料
(4) ;
}
class Espresso extends Beverage { //蒸馏咖啡
private final int ESPRESSO_PRICE = 25;
public Espress0() { description="Espresso"; }
public int cost() { return ESPRESSO_PRICE; }
}
class DarkRoast extends Beverage { //深度烘焙咖啡
private finalint DARKROAST_PRICE = 20;
public DarkRoast() { description = "DarkRoast"; }
public int cost(){ rcturn DARKROAST PRICE; }
}
class Mocha extends CondimentDecorator { //摩卡
private final int MOCHA_PRICE = 10;
public Mocha(Beverage beverage) {
this.beverage = beverage;
}
public String getDescription() {
return beverage.getDescription0 + ", Mocha";
}
public int cost() {
return MOCHA_PRICE + beverage.cost();
}
}
class Whip extends CondimentDecorator { //奶泡
private finalint WHIP_PRICE = 8;
public Whip(Beverage beverage) { this.beverage = beverage; }
public String getDescription() {
return beverage.getDescription()+", Whip";
}
public int cost() { return WHIP_PRICE + beverage.cost(); }
}
public class Coffee {
public static void main(String args[]) {
Beverage beverage = new DarkRoast();
beverage=new Mocha(5);
beverage=new Whip (6);
System.out.println(beverage.getDescription0 +"¥" +beverage.cost());
}
}
编译运行上述程序,其输出结果为:
DarkRoast, Mocha, Whip ¥38
试题10
阅读下列说明和C++代码,将应填入(n)处的字句写在答题纸的对应栏内。
【说明】
某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图15-32所示。

图15-32状态图
采用状态( State)模式来实现该纸巾售卖机,得到如图15-33所示的类图。其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类SoldState、SoldOutState、NoQuarterState和HasQuarterState分别对应图15-32中纸巾售卖机的4种状态:售出纸巾、纸巾售完、没有投币、有2元钱。

图15-33类图
【C++代码】
#include
using namespace std;
∥以下为类的定义部分
class TissueMachine; //类的提前引用
class State{
public:
virtual void insertQuarter()=0;//投币
virtual void ejectQuarter()=0;//退币
virtual void turnCrank()=0;//按下“出纸巾”按钮
virtual void dispense()=0;//出纸巾
};
/*类SoldOutState. NoQuarterState. HasQuarterState. SoldState的定义省略,每个类中均定义了私有数据成员TissueMachine* tissueMachine;*/
class TissueMachine{
private:
(1) *soldOutState, *noQuarterState, *hasQuarterState,*soldState, *state;
int count, //纸巾数
public:
TissueMachine(int numbers);
void setState(State* state);
State* getHasQuarterState();
State* getNoQuarterState();
State* getSoldState();
State* getSoldOutState();
int getCount();
//其余代码省略
};
//以下为类的实现部分
void NoQuarterState::insertQuarter(){
tissueMachine->setState( (2) );
}
void HasQuarterState::ejectQuarter(){
tissueMachine->setState( (3) );
}
void SoldState::dispense(){
if(tissueMachine->getCount()>0){
tissueMachine->setState ( (4) );
}
else{
tissueMachine->setState( (5) );
}
}//其余代码省略
试题11
阅读下列说明和Java代码,将应填入(n)处的字句写在答题纸的对应栏内。
【说明】
某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图15-34所示。

图15-34纸巾售卖机状态图
采用状态( State)模式来实现该纸巾售卖机,得到如图15-35所示的类图。其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类SoldState、SoldOutState、NoQuarterState和HasQuarterState分别对应图15-34中纸巾售卖机的4种状态:售出纸巾、纸巾售完、没有投币、有2元钱。

图15-35 类图
【Java代码】
import java.util.*;
interface State{
public void insertQuarter(); //投币
public void ejectQuarter(); //退币
public void turnCrank();//按下“出纸巾”按钮
public void dispense(); //出纸巾
}
class TissueMachine {
( 1 ) soldOutState, noQuarterState, hasQuarterState, soldState, state;
state = soldOutState;
int count = 0; //纸巾数
public TissueMachine(intnumbers) { /*实现代码省略 */}
public StategetHasQuarterState() { returnhasQuarterState; }
public StategetNoQuarterState() { returnnoQuarterState; }
public State getSoldState() { return soldState; }
public State getSoldOutState() { return soldOutState; }
public int getCount() { return count; }
//其余代码省略
}
class NoQuarterState implements State {
TissueMachine tissueMachine;
public void insertQuarter() {
tissueMachine.setState((2));
}
//构造方法以及其余代码省略
}
class HasQuarterState implements State {
TissueMachine tissueMachine;
public void ejectQuarter() {
tissueMachine.setState ((3));
}
//构造方法以及其余代码省略
}
class SoldState implements State {
TissueMachine tissueMachine;
public void dispense() {
if(tissueMachine.getCount() > 0) {
tissueMachine.setState ((4));
} else {
tissueMachine.setState ((5)); }
}
}
试题12
阅读下列说明和C++代码,将应填入空(n)处的字句写在答题纸的对应栏内。
【说明】
某饭店在不同的时段提供多种不同的餐饮,其菜单的结构图如图15-36所示。

图15-36 菜单结构图
现在采用组合(Composition)模式来构造该饭店的菜单,使得饭店可以方便地在其中增加新的餐饮形式,得到如图15-37所示的类图。其中MenuComponent为抽象类,定义了添加(add)新菜单和打印饭店所有菜单信息(print)的方法接口。类Menu表示饭店提供的每种餐饮形式的菜单,如煎饼屋菜单、咖啡屋菜单等。每种菜单中都可以添加子菜单,例如图15-36中的甜点菜单。类MenuItem表示菜单中的菜式。

图15-37 类图
【C++代码】
#include
#include
#include
using namespace std;
class MenuComponent{
protected: string name;
public:
MenuComponent(string name){ this->name= name;}
string getName(){ return name;}
(1) ; //添加新菜单
virtual void print()=0; //打印菜单信息
};
class MenuItem: public MenuComponent{
private:double price;
public:
Menultem(string name, double price):MenuComponent(name)
{ this->price= price;}
double getPrice(){ return price;}
void add(MenuComponent* menuComponent){ return;}//添加新菜单
void print(){ cout<<" " <<getname()<<","<<getprice()<<endl;}< p="">
};
class Menu:public MenuComponent{
private: list< (2)> menuComponents;
public:
Menu(string name):MenuComponent(name){}
void add(MenuComponent* menuComponent) //添加新菜单
{ (3) ; }
void print(){
cout<<"\n"<<getname()<<"\n-------------------"<<endl;< p="">
std::list
for(iter= menuComponents.begin(); iter!=menuComponents.end(); iter++)
(4)->print();
}
}
void main(){
MenuComponent* allMenus= new Menu("ALL MENUS");
MenuComponent* dinerMenu= new Menu("DINER MENU");
……//创建更多的Menu对象,此处代码省略
allMenus->add(dinerMenu); //将dinerMenu添加到餐厅菜单中
……//为餐厅增加更多的菜单,此处代码省略
(5) ->print(); //打印饭店所有菜单的信息
}
试题13
阅读下列说明和Java代码,将应填入(n)处的字句写在答题纸的对应栏内。
【说明】
某饭店在不同的时段提供多种不同的餐饮,其菜单的结构图如图15-38所示。

图15-38 菜单结构图
现在采用组合( Composition)模式来构造该饭店的菜单,使得饭店可以方便地在其中增加新的餐饮形式,得到如图15-39所示的类图。其中MenuComponent为抽象类,定义了添加(add)新菜单和打印饭店所有菜单信息(print)的方法接口。类Menu表示饭店提供的每种餐饮形式的菜单,如煎饼屋菜单、咖啡屋菜单等。每种菜单中都可以添加子菜单,例如图15-38中的甜点菜单。类MenuItem表示菜单中的菜式。

图15-39 类图
【Java代码】
import java.util.*;
(1)MenuComponent{
protected String name;
(2);//添加新菜单
public abstract void print(); //打印菜单信息
public String getName(){ return name;}
}
class Menultem extends MenuComponent{
private double price;
public MenuItem(String name, double price){
this.name= name; this.price= price;
}
public double getPrice(){return price;)
public void add(MenuComponent menuComponent){ return;} //添加新菜单
public void print(){
System.out.print(" "+ getName());
System.out.println(","+ getPrice());
}
}
class Menu extends MenuComponent{
private List
public Menu(String name){ this.name= name;)
public void add(MenuComponent menuComponent){//添加新菜单
menuComponents.(3);
}
public void print(){
System.out.print("\n"+ getName());
System.out.println(","+"---------------");
Iterator iterator - menuComponents.iteratoro;
while(iterator.hasNext()){
MenuComponent menuComponent= (MenuComponent)iterator.next();
(4);
}
}