I wonder if a state machine is just the state pattern at work or if there is actually a difference between those two?
I found this article with the bold title "the state design pattern vs state machine" but at the end of the day he only says that the state pattern makes state machines obsolete but then doesn't describe what exactly is a state machine compared to the implementation of the state pattern.
The state design pattern is not meant to implement a state machine. The emphasis of the state design pattern is on encapsulation of behavior to create reusable, maintainable components.
The state pattern is a behavioral software design pattern that allows an object to alter its behavior when its internal state changes. This pattern is close to the concept of finite-state machines.
A state machine is a mathematical abstraction used to design algorithms. A state machine reads a set of inputs and changes to a different state based on those inputs. A state is a description of the status of a system waiting to execute a transition.
In the State design pattern, an object's behavior is the result of the function of its state, and the behavior gets changed at runtime depending on the state. This removes the dependency on the if/else or switch/case conditional logic.
The way I describe this difference to my colleagues is that state patterns are a more decentralized implementation of many stand alone encapsulated states whereas state machines are more monolithic. The monolithic nature of state machines means that a single state will be harder to reuse in a different machine and that it is harder to break a state machine up into multiple compilation units. On the other hand this monolithic design allows far better optimization of state machines and allows many implementations to represent all transition information in one place in a table. This is especially suited for situations where the person responsible for the state machine architecture or function is not well versed in the programming language it is implemented in. Remember that many engineering and Math majors have learned about state machines but have little or no education in the programming field. It is far far easier to present these types of people with a table of transitions, actions and guards than pages and pages of state patterns.
Although the article actually was a good read I disagree with the author on several points:
Notice that switching states requires an allocation! this is going to kill speed. This could be remedied by placement allocating all states in a buffer next to each other in order to save a cache miss or two. However this would require major changes to the Authors example.
Also notice that events that are not handled cannot be inlined and optimized away like in static state machines because with the state pattern they are behind a layer of dynamic indirection. This is also a potential efficiency killer depending on your requirements.
From a maintenance standpoint it should be noted that logging unhandled events cannot be done from one central superstate with the state pattern. Also the addition of a new event type/handler function requires adding a function to all states! I don't consider that maintenance friendly.
I also prefer seeing all transitions in a table rather than looking through the inner workings of every state. The author is right that adding a state is easier but only very minimally, with boost statecharts for example I only have to add the state to the list of its parents child states, that is the only real difference.
I do use the state pattern in cases where speed is a non issue and where the hierarchy of the state machine will most likely remain flat. The author is correct that the initial implementation is usually easier with the state pattern compared to a state machine and that generally more programmers should use more state machines.
One Argument for the state pattern is that it allows the implementation of "Open Closed" state machines where a state machine can be defined in a library and then expanded on by the user, this is not possible as far as I know with mainstream state machine frameworks.
In case anyone still interested, here is my view:
In state machine, the object can be in different states, but we don't really care how they behave in those states. In fact, we only care what action is applied when the object is transitioned to the next state. If you implement a state machine in Java, a state will be just an enum, or a String and there will be a Transition class with doAction() method.
On the other hand, in state pattern, you don't really care about the transition, but how the object behave in those states. The transition is just an implementation details to make your state behaviors decoupled from each other. Each state will be a separate class, having doAction() method of its own.
Saying state pattern makes state machine obsolete is incorrect. State pattern will be useful if the behavior of each state is important, e.g in game programming, where an object can have states like "idle", "attack", "run" and in each state you want to implement the behavior of the object.
But for use case like ordering online products, where you don't care how the order object behaves. You only care if the order is in "added_to_cart" state, when a "payment_finished" event is published, then change it to "processing" state. In this case state is a simple enum property of the Order class, thus using state machine is much better.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With