我开始实现一个带有状态机的系统。但我怀疑状态机是否是正确的方法。
例如:我有四种状态:
(空闲、通电、断电、工作)
以及其他两个状态:
(生产、测试)
上电和断电在生产和测试状态下的表现确实不同......
如果我确实有更多状态,状态组合就会爆炸......
如何用状态机解决这个问题?
这有点难以回答,因为实际用例非常模糊,但这里有一些可能的技术:
优点:简单。
缺点:混乱,扩展性不好,如果某些状态逻辑在实例之间共享,则会涉及一些复制意大利面(因此,不太可维护)
因此,在您的示例中,您将拥有一个生产/测试状态机,并且每个状态机都将在内部实现自己的空闲/通电/断电/工作状态机。
如果你仔细想想,这实际上是选项 1 的更简洁的实现。
优点:比选项 1 更具可读性
缺点:假设子状态应该共享一些共同的逻辑,仍然会涉及复制粘贴
在您的示例中,您的代理或系统将是上述状态机的容器并依次处理它们。生产/测试机器会将一些状态写入共享内存,另一台机器将从该共享内存中读取并相应地分支其状态逻辑。
优点:可以在不同状态之间共享代码
缺点:可以在不同状态之间共享代码...好吧,说实话,强调共享代码并不总是一个好主意非常重要(但这完全是另一个哲学讨论。只要确保您正确评估共享的数量即可代码与唯一代码或路径的数量,这样你就不会得到一个本质上包含 2 个完全独立的代码路径的巨大类
事实上,如果状态机上只有 2 个状态,则可以使用变量来实现该目的。因此,您将拥有一个状态机,它将根据变量的值执行不同的工作。
switch(state)
{
case powerup:
switch(mode)
{
case test:
test_powerup_stuff();
break;
case production:
production_powerup_stuff();
break;
default:
break;
}
break;
case powerdown:
switch(mode)
{
case test:
test_powerdown_stuff();
break;
case production:
production_powerdown_stuff();
break;
default:
break;
}
break;
case idle:
do_idle_stuff();
break;
case work:
do_work_stuff();
break;
default:
state = powerdown;
break;
}
另一种选择是生产和测试可以是单台机器的“正交区域”。