设计模式与软考试题之状态模式(二)

2011年下半年软件设计师考试下午试题最后一题考查状态模式,在本试题中,命题人设计了一个具有多个状态的纸巾售卖机真题如下:

【全国计算机技术与软件专业技术资格(水平)考试 2011 年下半年 软件设计师 下午试卷】


注:当年试题五和试题六二选一,试题五为C++版,试题六为Java版。

试题五

阅读以下说明和 C++代码,将应填入 (n) 处的字句写在答题纸的对应栏内。

【说明】

某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图5-1所示。

5-1 纸巾售卖机状态图

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

5-2 类图

C++代码】

#include <iostream>

using namespace std;

// 以下为类的定义部分

class TissueMachine; // 类的提前引用

class State {

public:

virtual void insertQuarter() = 0; //投币

virtual void ejectQuarter() = 0; //退币

virtual void turnCrank()= 0; //按下“出纸巾”按钮

virtual void dispense() = 0; //出纸巾

};

/* SoldOutStateNoQuarterStateHasQuarterStateSoldState的定义省略,每个类中均定义了私有数据成员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 );

}

} //其余代码省略

试题六

阅读以下说明以及Java程序,将应填入 (n) 处的字句写在答题纸的对应栏内。

【说明】

某大型商场内安装了多个简易的纸巾售卖机,自动出售2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态图如图6-1所示。

6-1 纸巾售卖机状态

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

6-2 类图

【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;

intcount = 0; //纸巾数

public TissueMachine(int numbers) {/* 实现代码省略 */ }

public State getHasQuarterState() { returnhasQuarterState; }

public State getNoQuarterState() {return noQuarterState; }

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 ); }

}

}

------------------------------------------------------------------------------------------------------------------------------------------------------

分析与解答:

与2006年下半年的那道题相比(参考:设计模式与软考试题之状态模式(一)),本题的难度更小,只提供了使用状态模式的解决方案,没有Non-Pattern解决方案。在环境类TissueMachine中,枚举了各种具体状态并定义了当前状态对象state,在声明状态对象时需使用抽象状态类State,因此空(1)为State。空(2)-空(5)没有啥技术含量,看图说话而已,偷笑,这几空都围绕对象状态之间的转换,只要看得懂图1并且知道各种对象状态与状态类之间的对应关系,回答起来就很容易了,例如第(2)空,具体状态类NoQuarterState对应“没有投币”状态,此时,当调用insertQuarter()方法时,纸巾售卖机的状态将切换到“有2元钱”,因此setState()方法中的参数应该为具体状态类HasQuarterState对象,该对象已存在于环境类TissueMachine中,可以通过tissueMachine->getHasQuarterState()或tissueMachine.getHasQuarterState()来获取,第(3)-(5)空与之类似。

在本试题中,状态的切换由具体状态类来完成,环境类负责维护各个具体状态类的实例。

微笑推荐:深入学习状态模式

参考答案:

【试题五】

(1) State

(2) tissueMachine->getHasQuarterState()

(3) tissueMachine->getNoQuarterState()

(4) tissueMachine->getNoQuarterState()

(5) tissueMachine->getSoldOutState()

【试题六】

(1) State

(2) tissueMachine.getHasQuarterState()

(3) tissueMachine.getNoQuarterState()

(4) tissueMachine.getNoQuarterState()

(5) tissueMachine.getSoldOutState()

【作者:刘伟 http://blog.csdn.net/lovelion

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值