Today I came across code that implemented a complex login process. The login flow was quite complex but what made the code really difficult to understand was how it was implemented. Notifications, delegates, and long case switch statements were used to implement the login flow.
This got me thinking, how many times in my developer career have I actually used a state machine? The answer is I did a just a few times in my professional career. But why are developers afraid or unaware of using state machines? It would make our life and especially the life of our co-workers much easier.
This post is meant to create more awareness about state machines in the app developer crowd. If you don’t know what state machines are, please read up on them first. Wikipedia is a good place to start, as always. State machine are also described in Design Pattern.
State machines are awesome
The main reason for using state machines is to help the design process. It is much easier to figure out all the possible edge conditions by drawing out the state machine on paper. This will make sure that your application will have less bugs and less undefined behavior. Also, it clearly defines which parts of the internal state of your object are exposed as external API.
Moreover, state machines have decades of math and CS research behind them about analyzing them, simplifying them, and much more. Once you realize that in management state machines are called business processes, you’ll find a wealth of information and tools at your disposal.
Recognizing the state machine pattern
Most apps contain several examples of state machines, including login and registration, ordering or payment. The problem is that you might not necessarily think of them as state machines while designing your application. Therefore, it is good to have some indicators to recognize them early on. The easiest way is to look at your data model:
- Adding a
stateorstatusfield to your model is the most obvious sign of a state machine. - Boolean fields are usually also a good indication, like
published, orpaid. Also timestamps that can have aNULLvalue likepublished_atandpaid_atare a usable sign. - Finally, having records that are only valid for a given period in time, like
subscriptionswith a start and end date.
When you decide that a state machine is the way to go for your problem at hand, there are many tools available to help you implement it. I found TransitionKit for Objective-C or SwiftState pretty cool. There are also state machine compilers but I won’t advice using them.
YAGNI?
You’ve probably heard of the YAGNI principle, it stands for: You Ain’t Gonna Need It. Especially in Agile projects developers try not to build solutions until they need them. However when your state machine has more than 4 states and 6 transitions you will gone need a state machine. Especially when you want to make sure your software stays stable and can be supported the next few years.
Hopefully, reading this text has made you more aware of state machines and you will be applying them more often.
