

设计模式与软考试题之状态模式(一)
source link: https://blog.csdn.net/LoveLion/article/details/8523214
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

设计模式与软考试题之状态模式(一)
从2006年-2012年,在全国计算机技术与软件专业技术资格(水平)考试软件设计师级别考试中,状态模式已两次作为下午试题的最后一题出现(参考:历年软件设计师下午考试试题汇总统计),分别是2006年下半年和2011年下半年的两次考试。
【全国计算机技术与软件专业技术资格(水平)考试 2006 年下半年 软件设计师 下午试卷】
注:当年试题六和试题七二选一,试题六为C++版,试题七为Java版。
试题六
阅读以下说明和 C++代码,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】
传输门是传输系统中的重要装置。传输门具有 Open(打开)、Closed(关闭)、Opening(正在打开)、StayOpen(保持打开)、Closing(正在关闭)五种状态。触发传输门状态转 换的事件有 click、complete 和 timeout 三种。事件与其相应的状态转换如图6-1 所示。
图6-1 传输门响应事件与其状态转换图
下面的【C++代码 1】与【C++代码 2】分别用两种不同的设计思路对传输门进行状态模拟,请填补代码中的空缺。
【C++代码 1】
const int CLOSED = 1; const int OPENING = 2;
const int OPEN = 3; const int CLOSING = 4;
const int STAYOPEN = 5; //定义状态变量,用不同整数表示不同状态
class Door {
private:
int state; //传输门当前状态
void setState(int state){ this->state = state; } //设置当前状态
public: Door():state(CLOSED){};
void getState() { //根据当前状态输出相应的字符串
switch(state) {
case OPENING: cout <<"OPENING" << endl; break;
case CLOSED: cout << "CLOSED" << endl; break;
case OPEN: cout << "OPEN" << endl; break;
case CLOSING: cout << "CLOSING" << endl; break;
case STAYOPEN: cout << "STAYOPEN" << endl; break;
void click() { //发生click事件时进行状态转换
if ((1) ) setState(OPENING);
else if ((2) ) setState(CLOSING);
else if ((3) ) setState(STAYOPEN);
void timeout(){ //发生timeout事件时进行状态转换
if (state == OPEN) setState(CLOSING);
void complete(){ //发生complete事件时进行状态转换
if (state == OPENING) setState(OPEN);
else if (state == CLOSING) setState(CLOSED);
int main() {
Door aDoor;
aDoor.getState();
aDoor.click();
aDoor.getState();
aDoor.complete();
aDoor.getState();
aDoor.click();
aDoor.getState();
aDoor.click();
aDoor.getState();
return 0;
【C++代码 2】
class Door {
public:
DoorState *CLOSED, *OPENING, *OPEN, *CLOSING, *STAYOPEN, *state;
Door();
virtual ~Door(){ …… //释放申请的内存,此处代码省略};
void setState(DoorState *state) { this->state = state; }
void getState(){
// 此处代码省略,本方法输出状态字符串,
// 例如,当前状态为CLOSED时,输出字符串为“CLOSED”
void click();
void timeout();
void complete();
Door::Door() {
CLOSED = new DoorClosed(this);
OPENING = new DoorOpening(this);
OPEN = new DoorOpen(this);
CLOSING = new DoorClosing(this);
STAYOPEN = new DoorStayOpen(this);
state = CLOSED;
void Door::click() { (4) ;}
void Door::timeout() { (5) ; }
void Door::complete() {(6) ; }
class DoorState { //定义一个抽象的状态,它是所有状态类的基类
protected: Door *door;
public:
DoorState(Door *door) { this->door = door; }
virtual ~DoorState(void);
virtual void click() {}
virtual void complete() {}
virtual void timeout() {}
class DoorClosed :public DoorState{ //定义一个基本的 Closed 状态
public:
DoorClosed(Door *door):DoorState(door) {}
virtual ~ DoorClosed (){}
void click();
void DoorClosed::click() {(7) ; }
// 其它状态类的定义与实现代码省略
int main() {
Door aDoor;
aDoor.getState(); aDoor.click(); aDoor.getState(); aDoor.complete();
aDoor.getState(); aDoor.timeout(); aDoor.getState(); return 0;
试题七
阅读以下说明以及Java程序,将应填入 (n) 处的字句写在答题纸的对应栏内。
【说明】
传输门是传输系统中的重要装置。传输门具有 Open(打开)、Closed(关闭)、Opening(正在打开)、StayOpen(保持打开)、Closing(正在关闭)五种状态。触发状态的转换事件有 click、complete 和 timeout 三种。事件与其相应的状态转换如图7-1所示。
图7-1 传输门响应事件与其状态转换图
下面的【Java 代码 1】与【Java 代码 2】分别用两种不同的设计思路对传输门进行状态模拟,请填补代码中的空缺。
【Java代码 1】
public class Door {
//定义状态变量,用不同的整数表示不同状态
public static final int CLOSED = 1;
public static final int OPENING = 2;
public static final int OPEN = 3;
public static final int CLOSING = 4;
public static final int STAYOPEN = 5;
private int state = CLOSED;
private void setState(int state){this.state = state;} //设置传输门当前状态
public void getState() {
// 此处代码省略,本方法输出状态字符串,
// 例如,当前状态为 CLOSED 时,输出字符串为”CLOSED”
public void click() { //发生 click 事件时进行状态转换
if ((1) ) setState(OPENING);
else if ( (2) ) setState(CLOSING);
else if ((3) ) setState(STAYOPEN);
//发生 timeout 事件时进行状态转换
public void timeout() { if (state == OPEN) setState(CLOSING); }
public void complete() { //发生 complete 事件时进行状态转换
if (state == OPENING) setState(OPEN);
else if (state == CLOSING) setState(CLOSED);
public static void main(String [] args){
Door aDoor = new Door();
aDoor.getState(); aDoor.click(); aDoor.getState(); aDoor.complete(); aDoor.getState(); aDoor.click(); aDoor.getState(); aDoor.click(); aDoor.getState(); return;
【Java代码 2】
public class Door {
public final DoorState CLOSED = new DoorClosed(this);
public final DoorState OPENING = new DoorOpening(this);
public final DoorState OPEN = new DoorOpen(this);
public final DoorState CLOSING = new DoorClosing(this);
public final DoorState STAYOPEN = new DoorStayOpen(this);
private DoorState state = CLOSED;
//设置传输门当前状态
public void setState(DoorState state){ this.state = state;}
public void getState(){ //根据当前状态输出对应的状态字符串
System.out.println(state.getClass().getName());
public void click() { (4) ;}//发生 click 事件时进行状态转换
public void timeout() { (5) ;}//发生 timeout 事件时进行状态转换
public void complete() { (6) ;}//发生 complete 事件时进行状态转换
public static void main(String[] args){
Door aDoor = new Door();
aDoor.getState(); aDoor.click(); aDoor.getState(); aDoor.complete();
aDoor.getState(); aDoor.timeout(); aDoor.getState(); return;
public abstract class DoorState { //定义所有状态类的基类
protected Door door ;
public DoorState(Door door) {this.door = door;}
public void click() {} public void complete() {} public void timeout() {}
class DoorClosed extends DoorState{ //定义一个基本的 Closed 状态
public DoorClosed(Door door) { super(door); }
public void click() { (7) ; }
//该类定义的其余代码省略
//其余代码省略
------------------------------------------------------------------------------------------------------------------------------------------------------
分析与解答:
本题前三空的难度不大,只要能够看懂状态图并读懂代码,正确填写应该没有太大问题,后四空略有难度,特别是最后一空。在本试题中提供了两种状态转换实现方案:
【方案一】(即代码一)没有用状态模式,将所有的状态转换代码都写到Door类中,每一个状态对应一个整型常量(状态变量),当Door的click()等方法被调用时,可以实现相应状态的转换,根据状态图,可以完成对(1)、(2)和(3)空的解答,例如当状态变量state为CLOSED或者CLOSING时,调用click()方法,状态将转换为OPENING。同理,当timeout()方法和complete()方法被调用时,某些状态之间也可以发生转换。
【方案二】(即代码二)使用了状态模式,Door类充当环境类,提供了抽象类DoorState充当抽象状态类,其子类,如DoorClosed、DoorOpening等,充当具体状态类。在环境类Door枚举了所有的状态,提供了一个setState()方法用于设置当前状态,此外,在Door的click()方法中调用状态类的click()方法,在Door的timeout()方法中调用状态类的timeout()方法,在Door的complete()方法中调用状态类的complete()方法。因此,(4)、(5)、(6)空用于实现间接调用。第(7)空用于实现状态的切换,当状态为DoorClosed时,如果调用click()方法,那么Door的当前状态将切换到OPENING,因此在第(7)空,将调用door对象的setState()方法,注入一个DoorOpening类型的对象,由于该对象已存在于Door中,无须再重新创建。在C++中,可以通过door->OPENING来获取,而在Java中则通过door.OPENING来获取。在本试题中,状态的切换由具体状态类来完成,由环境类来维护各个具体状态类的实例。
推荐:深入学习状态模式
参考答案:
【试题六】
(1) state == CLOSED || state == CLOSING
(2) state == OPENING || state == STAYOPEN
(3) state == OPEN
(4) state -> click()
(5) state -> timeout()
(6) state -> complete()
(7) door -> setState(door->OPENING)
【试题七】
(1) state == CLOSED || state == CLOSING
(2) state == OPENING || state == STAYOPEN
(3) state == OPEN
(4) state.click()
(5) state.timeout()
(6) state.complete()
(7) door.setState(door.OPENING)
【作者:刘伟 http://blog.csdn.net/lovelion】
Recommend
-
60
有问题,上知乎。知乎是中文互联网知名知识分享平台,以「知识连接一切」为愿景,致力于构建一个人人都可以便捷接入的知识分享网络,让人们便捷地与世界分享知识、经验和见解,发现更大的世界。
-
38
状态模式主要用于状态机的设计,更加便利的控制切换对象状态,增强可扩展性和可维护性。状态机不仅适用于角色动作状态,...
-
49
-
45
前言 之前在我的博客(一枝花算不算浪漫)中已经更新过两篇设计模式相关的内容 【一起学设计模式】策略模式实战一:基于消息发送的策略模式实战
-
26
-
14
Python 设计模式——状态模式 发表于 2020-12-26 ...
-
11
设计模式与软考试题之职责链模式 2007年下半年软件设计师...
-
11
设计模式与软考试题之状态模式(二) 2011年下半年软件设计...
-
3
设计模式与软考试题之桥接模式 2009年上半年软件设计师考试下...
-
5
设计模式与软考试题之模板方法模式 2008年下半年软件...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK