State machine pattern

created: 4 months ago
updated: 2 months ago
new
  • patterns
  • code improvements

Intro

In this article you will implement coffee machine with a state machine pattern.

Imagine an ancient coffee machine. You can control the stages of coffee preparation manually and decide when a dedicated step should be performed.
Express can be destroyed if you press the button at the wrong moment. How do you know if now is the right time to grind coffee? It is much more convenient to have the software (state machine) which handles that.
1. State machine
The state machine is a mechanism that handles the correct order of steps in the process.
In the image below you can see states inside rectangles and actions that are displayed above lines. These actions trigger a state change. They can have additional data like temperature which can be needed for other states to work.
2. Implementation
In code, the state can be reflected via object. In our code, we use functions to create these objects. This reduces boilerplate and gives good type safety.
Transitions from one state to another are implemented by using references to other functions in objects. If there will be an attempt to change state in invalid order - you will get an exception.
Function declarations are hoisted. It means we don't need to worry about the correct order of declarations. This would not be possible with classes or function expressions.
3. Black box
Helper function reduces boilerplate and makes the whole state machine black-boxed. It reduces solution flexibility - you want this. After all, the coffee machine does not start with a state other than Idle.
4. Example of usage in React
If you want to use your state machine, it's a good idea to create a facade hook to expose consistent API / reuse it later in another view. You will have always a union of possible states because of the exhaustiveness checking mechanism from TypeScript.
5. You can make it generic
After several attempts, I think it's not worth it. That's because of the additional complexity which we adding. The decision is on your side.
Instead of implementing it from scratch, you can use prod ready solution - xstate library which gives additional features and adds cool visualization.
After this short adventure, you probably understand what the state machine can do for you. Usage of this pattern dramatically improves your code base, especially in complex state management.
Feel free to contact me if you have any questions/proposals. Have a nice day and good health!
"With great power is also great responsibility" - Uncle Bob.