在什么情况下我们应该采用州模式?
我被分配到维护一个项目,项目状态机由switch-case实现,长度超过2000行。扩展功能很难,所以我想重构一下。 我正在调查州的设计模式,但我有一些困惑。
一个简单的例子:
1。初始状态“WAIT”,等待用户发送下载命令
2。用户发送下载命令时,移至“CONNECT”状态,连接服务器
3。创建连接后,转到“DOWNLOADING”状态,保持从服务器接收数据
4。数据下载完成后,移至“DISCONNECT”,断开与服务器的链接
5。断开连接后,进入“WAIT”状态,等待用户发送下载命令
方法1:在我调查状态模式之前,我认为一个简单的方法---在不同的函数中包装不同的状态行为,使用函数指针数组指向每个状态函数,并通过调用函数改变状态。 / p>
typedef enum {
WAIT,
CONNECT,
DOWNLOADING,
DISCONNECT
}state;
void (*statefunction[MAX_STATE])(void) =
{
WAITState,
CONNECTState,
DOWNLOADINGState,
DISCONNECTState
};
void WAITState(void)
{
//do wait behavior
//while receive download command
//statefunction[CONNECT]();
}
void CONNECTState(void)
{
//do connect behavior
//while connect complete
//statefunction[DOWNLOADING]();
}
void DOWNLOADINGState(void)
{
//do downloading behavior
//while download complete
//statefunction[DISCONNECT]();
}
void DISCONNECTState(void)
{
//do disconnect behavior
//while disconnect complete
//statefunction[WAIT]();
}
方法2:状态模式在不同的类(面向对象的状态机)中封装不同的状态及其行为,使用多态实现不同的状态行为,并为所有具体状态定义一个公共接口。
class State
{
public:
virtual void Handle(Context *pContext) = 0;
};
class Context
{
public:
Context(State *pState) : m_pState(pState){}
void Request()
{
if (m_pState)
{
m_pState->Handle(this);
}
}
private:
State *m_pState;
};
class WAIT : public State
{
public:
virtual void Handle(Context *pContext)
{
//do wait behavior
}
};
class CONNECT : public State
{
public:
virtual void Handle(Context *pContext)
{
//do connect behavior
}
};
class DOWNLOADING : public State
{
public:
virtual void Handle(Context *pContext)
{
//do downloading behavior
}
};
class DISCONNECT : public State
{
public:
virtual void Handle(Context *pContext)
{
//do disconnect behavior
}
};
我想知道状态模式是否比这种情况下的函数指针要好... 仅使用函数指针也可以提高可读性(与switch-case相比),而且更简单。 状态模式将创建几个类,并且比仅使用函数指针更复杂。 使用状态模式有什么好处?
谢谢你的时间!
答案 0 :(得分:0)
使用状态模式有什么好处?
首先,需要注意的是,两个你提供的方法, 实际上是相同模式的例子 。其中一种方法描述了基于函数的实现,而另一种方法更多地采用了面向对象的方法。
话虽这么说,模式本身有一些优点:
由于您将问题标记为与c++相关,因此最好考虑语言提供和要求的内容。虽然classes
提供继承,但是大量的类可以大大增加编译时间。因此,当涉及到实现时,如果您的状态机大,static polymorphism可能是最佳选择。