我对如何实现我的状态机有点困惑。
我已经知道它是分层的,因为某些州共享相同的操作。
我通过这些参数确定我需要做什么:
- 类(值是:Base、Derived、Specific)
- 操作码
- 参数 1 - 可选
- 参数 2 - 可选
我的层次结构由 Class 确定,OpCode代表操作。
Derived可以使用Base的OpCodes,Specific可以使用Base和Derived的OpCodes。
天真的实现如下:
void (*const state_table [MAX_CLASSES][MAX_OPCODES]) (state *) {
{base_state1, base_state2, NULL, NULL},
{base_state1, base_state2, derived_state1, NULL},
{base_state1,base_state2, derived_state1, specific_state3},
};
void dispatch(state *s)
{
if (state_table[s->Class][s->OpCode] != NULL)
state_table[s->Class][s->OpCode](s);
}
这将很快变得无法维护。
还有另一种方法可以将状态映射到超类吗?
编辑:
进一步的计算使我认为我可能会使用大多数(如果不是全部)操作码,但我不会使用所有可用的类。
另一个澄清:
一些OpCodes可能通过多个派生类和基类共享。
例如:
- 我有一个名为Any的类 ,它是一个基类。它有 OpCodes:STATE_ON,STATE_OFF,STATE_SET。
我有另一个名为 MyGroup的类,它是一个派生类。它有OpCodes: STATE_FLIP,STATE_FLOP。
第三个类是一个 名为ThingInMyGroup的特定类,它具有OpCode: STATE_FLIP_FLOP_AND_FLOOP。
因此,从服务器发送 一条Any类的消息,在所有客户端中接收并处理。
从服务器发送一条MyGroup类的消息,在所有客户端中接收并仅在属于MyGroup的客户端上处理,任何对Any类有效的操作码对MyGroup类有效。
从服务器发送具有ThingInMyGroup类的消息,在所有客户端中接收并仅在属于MyGroup并且是ThingInMyGroup* 的客户端上处理,任何对Any类和MyGroup类有效的 **OpCodes 对ThingInMyGroup类有效.
收到消息后,客户端将相应地 ACK/NACK。
我不喜欢使用 switch case 或 const 数组,因为当它们变大时它们将变得无法维护。
我需要一个灵活的设计,让我:
- 为每个Class指定哪些OpCodes可用。
- 为每个Class指定一个超类,并通过该规范允许我调用由当前OpCode表示的函数指针。