天哪,它并不像看起来那么复杂。状态机代码非常简单和简短。
将状态存储在一个变量中,比如 myState。
您的状态机将是一个 switch 语句,在 myState 变量的值上进行分支以执行每个状态的代码。
代码将充满这样的行:
myState = newState;
要强制执行状态转换要求,您需要添加一个名为的小方法,如下所示
void DoSafeStateTransition( int newState )
{
// check myState -. newState is not forbidden
// lots of ways to do this
// perhaps nested switch statement
switch( myState ) {
…
case X: switch( newState )
case A: case B: case Z: HorribleError( newState );
break;
...
}
// check that newState is not undetermined
switch( newState ) {
// all the determined states
case A: case B: case C … case Z: myState = newState; break;
default: HorribleError( newState );
}
}
void HorribleError( int newState )
{ printf("Attempt to go from %d to %d - disallowed\n",
myState, newState );
exit(1);
}
我建议这个简单而简短,以至于检查会比单元测试做得更好——它肯定会快很多!
在我看来,单元测试的重点是测试代码比测试代码更简单,因此可以更容易地检查其正确性,然后用于测试复杂的代码。检查状态机代码通常比检查状态机测试代码更容易。当您几乎不知道单元测试是否正确时,报告 100% 单元测试通过并没有多大意义。
换句话说:编写状态机很容易,设计正确的状态机很难。单元测试只会告诉您是否正确编码了设计,而不是设计是否正确。