下面可能是C ++中简单状态机的实现。类 Tokenizer 维护"标记化状态变量",并返回标记,就像来自字符流的HTML标记一样。
是否有任何理由将Tokenizer类中的函数handle_xxx()移出;
如果是,那么为什么&如何?
#include <iostream>
#include <map>
class Token;
class CharacterReader;
class Tokenizer {
TokenizerState current_state;
CharacterReader r;
std:map<TokenizerState, void (Tokenizer::*pmf)()> stateMap;
public:
// Tokenizer States
typedef enum { INITIAL = 0, STATE_1, STATE_2, END } TokenizerState;
// State Handlers
void handle_Initial();
void handle_State_1();
void handle_State_2();
// 20 more states before END...
void handle_End();
Tokenizer(String text_to_tokenize)
{
stateMap[INITIAL] = handle_Initial;
stateMap[STATE_1] = handle_State_1;
stateMap[STATE_2] = handle_State_2;
stateMap[END] = handle_End;
current_state = TokenizerState::INITIAL;
r.set(text_to_tokenize);
}
void switchState(TokenizerState s) { current_state = s; }
void run() {
while (current_state!=TokenizerState::END) {
Token token = stateMap[current_state]();
// do something with the Token
}
}
};
void Tokenizer::handle_Initial() {
}
void Tokenizer::handle_State_1() {
char c = r++;
switch(c) {
case 'a':
break;
case 'b':
ts.switchState(Tokenizer::TokenizerState::STATE_2);
}
}
void Tokenizer::handle_State_2() {
}
void Tokenizer::handle_End() {
}
答案 0 :(得分:0)
恕我直言,最好的方法是将所有handle_XXX()
(将 XXX 作为状态机触发事件)方法移出到单独的接口,并为每个接口提供不同的实现方法已确定的州。 handle_XXX()
方法的实现可以接收对当前状态机实例的引用,并对其进行操作/操作(包括触发状态更改)。
这就是众所周知的State Pattern
中提出的内容我在您的实现中看到的一个当前缺陷是,您错过了映射实际事件以将它们分派给不同的处理程序。
在你提供的基础上继续使用可理解的代码示例是没有意义的。我希望你能指出我的想法。
答案 1 :(得分:-1)
为什么不定义Tokenizer Handler类,并将其实例传递给Tokenizer类?引用成员函数的方法可能仍然有效。