Reputation: 55
I started to implement a system with a state machine. But I came to a point where I doubt that a state machine is the correct approach.
For example: I have four states:
(idle, powerup, powerdown, work)
and two other states:
(production, test)
powerup and powerdown do behave different in production and test state ...
If I do have more states the combination of states explodes ...
How is this solved with a state machine?
Upvotes: 3
Views: 6779
Reputation: 161
That's a bit difficult to answer since the actual use case is very vague, but here are some possible techniques:
Pros: straightforward.
Cons: cluttered, does not scale well, if some of the state logic is shared across instances there will be some copy pasta involved (hence, not very maintainable)
So in your example, you would have a Production/Test state machine, and each one will implement it's own Idle/Powerup/Powerdown/Work state machine internally.
If you think this over, this is actually a neater implementation of option 1.
Pros: more readable than option 1
Cons: assuming substates should share some common logic, there will still be copy pasting involved
In your example, your agent or system will a container of the above mentioned state machines and process them in turn. The Production/Test machine would write some status to a shared memory that the other machine will read from and branch it's state logic accordingly.
Pros: Can share code between different states
Cons: Can share code between different states... Ok, serioulsy, it's super important to empashize that sharing code is NOT always a good idea (but that's a whole other phylosophical discussion. Just make sure you properly evaluate the amount of shared code vs. the amount of unique code or paths so you don't end up with a huge class that essentially contains 2 completely separate code paths
Upvotes: 3
Reputation: 1975
The feeling that your state machine "explodes" is very typical in traditional "flat" FSMs (in fact it is generally known as the "state-transition explosion" phenomenon). The remedy is to use a hierarchical state machine (HSM) instead, which specifically counteracts the "explosion" of a traditional FSM. Basically, the HSM allows you to group states with similar behavior together (inside a higher-level super-state) and thus reuse the common behavior among the related states. This is a very powerful concept that leads to much more elegant and consistent designs. To learn more about hierarchical state machines, you can read the article "Introduction to Hierarchical State Machines".
Upvotes: 2
Reputation: 2000
Could it be that you need two instances of the same state machine model? One for production and one for test?
An alternative is that production and test could be orthogonal regions of a single machine.
Upvotes: 0
Reputation: 882
I would classify 'production' and 'test' as modes, not states. It will still be somewhat messy, but the distinction is important, in my opinion.
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;
}
Upvotes: 0
Reputation: 77
A state machine can share signal with another one. So the state machine that indicate prod or dev can send a signal to the other one.
In fact, if you have only 2 state on the state machine, you can use a variable for that purpose. So you will have one state machine that will do different job depending on the value of the variable.
Upvotes: 0