Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between a state machine and the implementation of the state pattern?

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.

like image 696
Christoph Avatar asked Nov 08 '13 12:11

Christoph


People also ask

Is the State pattern a state machine?

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.

What is a state machine pattern?

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.

What does a state machine do?

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.

What a state does in state design pattern?

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.


2 Answers

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:

  • "There is no reason to use state machines anymore when you are using an object oriented programming language" this is categorically not true if you have any requirement on execution speed.
  • The idea that the authors implementation is particularly short or simple or that it requires less maintenance than the boost statecharts digital camera depends on your use case and personal taste but can not be said catagorically. http://www.boost.org/doc/libs/1_55_0/libs/statechart/doc/tutorial.html#IntermediateTopicsADigitalCamera

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.

like image 136
odinthenerd Avatar answered Sep 24 '22 22:09

odinthenerd


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.

like image 21
Bùi Anh Dũng Avatar answered Sep 21 '22 22:09

Bùi Anh Dũng