在什么情况下我们应该采用状态模式?
我已经被分配去维护一个项目,项目状态机是通过2000年以上的开关盒实现的。扩展功能将很困难,因此我想对其进行重构。我正在调查状态设计模式,但是有些困惑。
一个简单的例子:
1。初始状态为“ WAIT”,等待用户发送下载命令
2。用户发送下载命令时,进入“连接”状态,连接到服务器
3。建立连接后,进入“下载中”状态,继续接收来自服务器的数据
4。数据下载完成后,移至“ DISCONNECT”,断开与服务器的链接
5。断开连接后,进入“等待”状态,等待用户发送下载命令
方法1:在研究状态模式之前,我认为是一种简单的方法---在不同的函数中包装不同的状态行为,使用函数指针数组指向每个状态函数,并通过调用函数更改状态。
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
}
};
我想知道在这种情况下状态模式是否比函数指针更糟糕...仅使用函数指针还可以提高可读性(与切换用例相比),并且更简单。状态模式将创建几个类,并且比仅使用函数指针要复杂得多。使用状态模式有什么优势?
感谢您的时间!
使用状态模式有什么好处?
首先,需要注意的是,您提供的方法中的both,实际上是the same pattern的示例。其中一种方法描述了基于函数的implementation,而另一种方法则采用了更多的面向对象方法。话虽这么说,该模式本身具有一些优点:
classes
提供了继承,但是大量的类会大大增加编译时间。因此,在实现方面,如果您的状态机为large