我开始使用状态机实现系统。但我发现我怀疑状态机是正确的方法。
例如:我有四种状态:
(空闲,通电,断电,工作)
以及其他两个州:
(生产,测试)
上电和断电在生产和测试状态下表现不同......
如果我确实有更多的州,那么国家组合会爆炸......
如何通过状态机解决这个问题?
答案 0 :(得分:1)
由于实际用例非常模糊,但有点难以回答,但这里有一些可能的技巧:
优点:直截了当。
缺点:混乱,不能很好地扩展,如果某些状态逻辑在实例之间共享,则会涉及一些复制意义(因此,不太可维护)
因此,在您的示例中,您将拥有一个生产/测试状态机,并且每个机器都将在内部实现它自己的空闲/加电/掉电/工作状态机。
如果你认为这一点,这实际上是选项1的更简洁的实现。
优点:比选项1更具可读性
缺点:假设子状态应该共享一些常见的登录,仍然会涉及复制粘贴
在您的示例中,您的代理或系统将是上述状态机的容器并依次处理它们。生产/测试机器会将一些状态写入另一台机器将读取的共享内存,并相应地分支它的状态逻辑。
优点:可以在不同状态之间共享代码
缺点:可以在不同的州之间共享代码......好的,严肃的,强调共享代码并不总是一个好主意(但这是一个完整的其他哲学讨论)只需确保正确评估共享代码的数量与唯一代码或路径的数量,这样您就不会得到一个基本上包含2个完全独立的代码路径的庞大类
答案 1 :(得分:1)
您的状态机“爆炸”的感觉在传统的“扁平”FSM中非常典型(实际上它通常被称为“状态转换爆炸”现象)。解决方法是使用分层状态机(HSM),它专门抵消传统FSM的“爆炸”。基本上,HSM允许您将具有相似行为的状态组合在一起(在更高级别的超级状态内),从而重用相关状态之间的共同行为。这是一个非常强大的概念,可以带来更加优雅和一致的设计。要了解有关分层状态机的更多信息,请阅读文章"Introduction to Hierarchical State Machines"。
答案 2 :(得分:0)
状态机可以与另一个共享信号。因此,指示prod或dev的状态机可以向另一个发送信号。
实际上,如果状态机上只有2个状态,则可以使用变量来实现此目的。因此,您将拥有一个状态机,它将根据变量的值执行不同的工作。
答案 3 :(得分:0)
我会将生产'分类。和'测试'作为模式,而不是国家。它仍然有些混乱,但在我看来,区别很重要。
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;
}
答案 4 :(得分:0)
是否需要两个相同状态机模型的实例?一个用于生产,一个用于测试?
另一种方法是生产和测试可以是单个机器的正交区域。