Using State Machines in Software Development

Marcel Kulina
3 min readOct 13, 2022

--

Most developers have heard about State machines. In this post, we will unveil the benefits of using State machines

What are State Machines?

State machines sometimes referred to as Finite State Machines (FSM), are abstract software machines that carry out steps in a fixed order. An FSM has a start state, an end state, and any number of interconnected states in between.

States are bound to conditions in such a way that not every step can be reached from any point. Instead, the FSM defines — or receives — instructions on how to operate on those states.

When the FSM gets a new instruction — often called command — it checks if the command is allowed in the current state. If it is, the FSM advances to the next state. If it is not, it can either do nothing or throw an error.

A very basic FSM that represents a login flow.

As you can see in the above example, state machines look very similar to what we are already doing in software.

Why are State Machines useful?

State machines are a very handy tool because they mimic the flow of user interaction precisely. Every situation and action during such flows can be described by a state or a command. As the concept of state machines itself is just a barebone collection of states, we can extend it to make it more suitable for our needs.

For example, we could introduce a callback method that will be called whenever a state transition occurs. Or we could as well pass data on command execution. How much business logic the state machine contains is up to the needs.

No matter how complex the internal logic is, outside code will only ever deal with issuing commands. This means we can abstract flows in our applications in a common way without needing to deal with several complex systems.

Another big advantage of state machines is thread safety. As we are processing commands, the state machine can halt the execution of other threads if they try to execute a command while another one is being executed.

State Machine vs Service

As state machine and service implementations greatly differ from each other, we will skip the implementation and instead focus on what using these patterns could look like.

The below examples show a very rudimentary way of using those patterns.

User login flow in realised with a state machine.
User login realised with a service

As you can see state machine code is more verbose but also more straightforward to read.

Especially when more requirements are needed, and an increased amount of states and commands are present, a state machine can be a lot more useful compared to services and similar patterns. This is because those patterns either expose a large number of methods or do many operations in a few methods. Both approaches mean that we can not fully understand what the current flow is operating on.

Where to Go From Here

As we have learned, state machines are a known concept to many developers, even if some don’t know that they are writing them. They have been around for a long time and are used in a broad range of applications. Especially games make heavy use of them.

State machines provide a safe and easy way of operating on flows which makes them very useful in many scenarios. Because of that, they deserve more credit.

--

--