在什么情况下我们应该采用国家模式
In what situation should we adopt state pattern?
在什么情况下我们应该采用状态模式?
我被指派维护一个项目,项目状态机是由2000多行长的交换机实现的。扩展函数会很困难,所以我想重构它。我正在调查国家设计模式,但我有一些困惑。
一个简单的例子:
1.初始状态"WAIT",等待用户发送下载命令
2.当用户发送下载命令时,移动到"CONNECT"状态,连接到服务器
3.创建连接后,转到"下载"状态,保持从服务器接收数据
4.当数据下载完成时,转到"断开连接",断开与服务器的链接
5.断开连接后,进入"WAIT"状态,等待用户发送下载命令
一种简单的状态机pic
-
方法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 } };
我想知道在这种情况下,状态模式是否比函数指针更棒。。。只使用函数指针也可以提高可读性(与开关情况相比),而且更简单。状态模式将创建多个类,并且比仅使用函数指针更复杂。使用状态模式的优点是什么?
谢谢你抽出时间!
使用状态模式的优点是什么?
首先,需要注意的是,您提供的两个方法实际上都是的示例,具有相同的模式。其中一种方法描述了基于函数的实现,而另一种方法则更多地采用了面向对象的方法。
也就是说,这种模式本身有几个优点:
- 它限制了程序可以处于的状态的数量,从而消除了未定义的状态
- 它允许通过添加新状态而不是重构整个代码来更容易地扩展应用程序
- 从公司的角度来看,这是安全的,即使多人在同一个班上工作
由于您将该问题标记为与c++相关,因此最好考虑到该语言的给出和要求。虽然classes
提供了继承,但大量的类可以大大增加编译时间。因此,当涉及到实现时,如果您的状态机很大,那么静态多态性可能是可行的。
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 为什么在保护模式下继承升级不起作用
- 如何在全屏模式下(在OpenGL中)使背景透明
- 为什么使用__LINE_的代码在发布模式下在MSVC下编译,而不是在调试模式下
- 派生类是否可以在抽象工厂设计模式中具有数据成员
- 此模式的C++RegEx
- avrogencpp能为模式中的每种类型生成单独的头文件吗
- 使用可变模板的Broadcaster/Listener模式
- c++方法参数只能在linux的发布模式下自行更改
- 资源管理设计模式
- 使用 mod_gsoap 部署服务时,如何在 Gsoap 中更改 soap 上下文的模式?
- C++ 无法在字符数组中使用 for 循环打印字母模式
- 小字符串优化(调试与发布模式)
- 可视化C++:发布模式的运行时库作为'Multi-threaded Debug DLL'
- 如何设计具有不同类型的通知和观察器的观察者模式?
- 在C++的一系列数字中查找重复模式
- 是否允许使用带有"w+"模式的 freopen 进行标准设置?
- C++ 使用存储在动态数组中的文本文件中的数据查找模式
- С++ wxWidgets:代码架构,设计原则和模式
- 在什么情况下我们应该采用国家模式