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

7

51

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.

Natalee answered 8/11, 2013 at 12:49 Comment(3)
Where exactly he says that state make state machines obsolete?Luik
Well he writes Also, I have seen state machines being used instead of state design patterns at the costs of horribly complicated software that is hard to maintain. There is no reason to use state machines anymore when you are using an object oriented programming language.Natalee
I think he refers to global state machines, such as OpenGL. And he's wrong... For example, in computer graphics, you have to have the highest performance you can, even if this means to write a global state machine. There is no recipee...Luik
S
28

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.

Serrulate answered 7/12, 2013 at 21:35 Comment(0)
F
19

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.

Fisher answered 25/4, 2018 at 15:28 Comment(1)
About your last paragraph, yes, I understand it and I think that state machine it is a good option. But from some point of view, doesn't it need to control the behavior? For example, I can't add an order if the chart is in processing state. I sumary, I mean that always there are conditions that some action can't be done according to the actual state.Chavis
C
13

A state machine can be designed and implemented in several ways. One way is to use the state pattern described in the book by the Gang of Four. But there are other patterns to implement a state machine.

For example, you may want to have a look at the research of Miro Samek by reading the book Practical UML statecharts in C/C++, 2nd ed. (Event-Driven Programming for Embedded Systems)

You may also find interesting this question.

Coquito answered 8/11, 2013 at 13:11 Comment(2)
I disagree. 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 focus of the finite state machine is on states and their transitions (captured by the state diagram) but not on the actual behavior (that’s an implementation detail). You can find my full argumentation in this article I wrote: medium.com/@1gravityllc/…Collocation
I agree with this answer. "State Pattern" is pattern to implement the "state machine"Volumetric
A
3

I notice a difference with state Pattern. its more handy when using it for UI. lets say i wanted to lock the state. in the state Pattern context i could create a boolean and prevent states from changing further.

here is a Kotlin example:

     inner class StateContext : State {

       private var stateContext: State? = null
       private var lockState: Boolean = false

       fun isLockState(): Boolean {
           return lockState
       }

       fun setLockState(lockState: Boolean): StateContext {
           this.lockState = lockState//no further actions allowed. useful if you need to permenatley lock out the user from changing state.
           return this
       }

       fun getState(): State? {
           return this.stateContext
       }

       fun setState(state: State): StateContext {
           if (!lockState) this.stateContext = state
           return this
       }

       override fun doAction() {
           this.stateContext?.doAction()
       }
   }

with state machine im not sure how that would be done easily.

i really like state machine when im worried about just the state (saving enum of current state for example ) , not the actual implementation detail (changing UI buttons color , for example) . the one thing about state machine thats good, is that you can have a central place to log state changes. i saw this library for kotlin by tinder which looks interesting. but i do personally think you could change them all to do what you want, just more cleaner one way vs another.

what is a stateMachine then ? the stateMachine cares more about "what is the next state", its highlighting transition of the states rather then its detail. It maintains a flow. Usually you create it using enums. this article helps clear it up ( and references below are taken from there to help clear up the differences) but essentially this would be a state machine:

public enum LeaveRequestState {

Submitted {
    @Override
    public LeaveRequestState nextState() {
        return Escalated;
    }

    @Override
    public String responsiblePerson() {
        return "Employee";
    }
},
Escalated {
    @Override
    public LeaveRequestState nextState() {
        return Approved;
    }

    @Override
    public String responsiblePerson() {
        return "Team Leader";
    }
},
Approved {
    @Override
    public LeaveRequestState nextState() {
        return this;
    }

    @Override
    public String responsiblePerson() {
        return "Department Manager";
    }
};

public abstract LeaveRequestState nextState(); 
public abstract String responsiblePerson();

}

now you know what the next transition state is for each event. So state machine CARES greatly for transitions over actually implementation of the state:

LeaveRequestState state = LeaveRequestState.Submitted;

state = state.nextState();
assertEquals(LeaveRequestState.Escalated, state);

state = state.nextState();
assertEquals(LeaveRequestState.Approved, state);

state = state.nextState();
assertEquals(LeaveRequestState.Approved, state);
Allegra answered 18/6, 2018 at 3:46 Comment(2)
with state machine im not sure how that would be done easily. This is exactly what state machines are meant for, control the flow of states and enforce only valid state transitions and thus states. There are many ways to implement a state machine and how state transitions are handled can vary greatly. Handling states with an enum is a rather crude implementation and doesn't offer much flexibility so locking a state might indeed be problematic with that approach. A more flexible approach is to let the states handle triggers and dispatch to the next state.Collocation
thats true about using enumsAllegra
C
2

a state machine is just the state pattern at work or if there is actually a difference between those two

TL;DR: Imagine you need to replace a state with a differently behaving one. Then imagine you need to add a new state.

Full Answer. There is a big difference.

The state pattern abstracts the states and decouples them from each other. So, for example, you can easily replace one particular state with another. Yet you will not be happy rewriting all the states when it is time to add a new one and/or a new transition.

The state machine abstracts the state diagram itself and decouples it from the transition payloads. To change a particular state, you have to fix the whole diagram. But to add a state or transition, you only need to fix the diagram.

Commonwealth answered 8/5, 2017 at 20:4 Comment(0)
W
2

That's how I understand it:

  • A state machine is a mathematical/engineering term. A mathematical model describing the state and state transitions of a computer such as a vending machine or a washing machine is presented in the form of a state diagram

  • State patterns are the name of programming. Design pattern is to better standardize the code design structure, so as to facilitate encapsulation, reuse, easy to expand; The state mode is used to solve the problem that objects show different behaviors according to their state

The correct relationship is that if you need to develop a "washing machine" programme, the product manager should draw a "statechart" to describe the "state machine", and then give it to the programmer to implement. The programmer can implement the state machine in a number of ways, but the best way to implement it is to use the State Pattern.

Whistling answered 17/2, 2022 at 6:58 Comment(0)
C
1

I wrote an article about the state design pattern and state machines: https://medium.com/@1gravityllc/the-super-state-design-pattern-166127ce7c9a. In the article I'm showing that their focus is different but that they are also not mutually exclusive. There's a way to combine the two to come up with a super state design pattern.

The emphasis of the state design pattern is on encapsulation of behavior to create reusable, maintainable components (the states).

The focus of the finite state machine is on states and their transitions (captured by the state diagram) but not on the actual behavior (that’s an implementation detail).

The article describes how these two concepts can be combined by using a finite state machine to describe and manage the states and their transitions for an object that delegates behavior to state objects using the state design pattern.

Collocation answered 18/2, 2020 at 0:34 Comment(8)
using "state pattern" , we can implement "finite state machine". is that not right?Volumetric
no the state design pattern has nothing to do with finite state machines, please read my article for more detailsCollocation
No..i think you are wrong. Martin fowler mentions that state machine can be implemented using simple switch / state table / state pattern.Volumetric
you're comparing apples and oranges, finite state machines are a computation model while the state design pattern is ... well a design pattern, you can certainly use the latter as part of a state machine implementation (as my article explains) but a state machine is more than encapsulated state behaviorCollocation
even apples and oranges have similarities. They both come under fruit category and we can extract juice! No one said "both are same". Now you have confirmed my first statement!Volumetric
The expression apples to oranges is an idiom to express that two things are incomparable or that a false analogy was made. It's pointless to argue that apples and oranges have similarities, you're basically arguing against the idiom.Collocation
As to your first statement, I confirm that the state design pattern can be used as part of a fsm implementation but it's only a small part and really not the essence of a fsm. The state design pattern deals with a specific aspect of the state machine only. "using "state pattern" , we can implement "finite state machine" implies to me, that the pattern is the whole deal, it's sufficient to implement a fsm (it's not) but maybe the question just wasn't clear enough or misunderstood by me. PeaceCollocation
Regarding "apples vs oranges" - instead of rejecting everything as "apples vs oranges" (in this case it is not), sharing the similarities is a good way to educate someone who has no clue. A person who understood a topic would not say "apples vs oranges".Volumetric

© 2022 - 2025 — McMap. All rights reserved.