4 Jun 2020
What is a finite state machine?
A finite-state machine (FSM) is a mathematical model of computation. It can change from one state to another in response to some inputs; the change from one state to another is called a transition. An FSM is defined by a list of its states, its initial state, and the inputs that trigger each transition.
Thank-you Wikipedia. That’s helpful.
Example for the layman
Let’s take a coke machine. You select a product. You input money. You get a can of fizzy pop. You get change.
The coke machine changes from state to state. At each state a decision is made about can be done next. You don’t get the can of pop until you have input enough money. And that’s a Stateful Machine.
Why use a State Machine?
A state machine lets me break down a complex process into a chain of smaller steps, where the movement from one step to another is a transition. It abstracts a lot of the logic concerning states & transitions out of the code, and it’s a really helpful way to visualise and to organise a system, and (going forward) to maintain it.
Signs that I should be using a state machine
- If an object status has many different states, then a state machine might be a good idea. For example, an order status could be started, paid, packed, shipped, cancelled, delivered, returned, credited, refunded etc.
- If there are lengthy switch statements or an horrendous amount of “if..else…” to work out exactly what actions we are allowed to perform, then maybe the Finite State Machine.
- If I ask a client to explain the workflow and they come back to me with an excel spreadsheet. That’s usually an indication that I should be configuring a state machine to manage transistions.
Using either of these libraries, my coke machine would look something like this:
$states => [ 'start', 'wait_for_money', 'check_money', 'dispense_product', 'give_change', 'finish' ]; $transistions => [ 'action_selectproduct' => [ 'from' => 'start', 'to' => 'wait_for_money' ], 'action_insertmoney' => [ 'from' => 'wait_for_money', 'to' => 'check_money' ], 'action_moremoney' => [ 'from' => 'check_money', 'to' => 'wait_for_money' ], 'action_enoughmoney' => [ 'from' => 'wait_for_money', 'to' => 'dispense_product' ], 'action_nothingowing' => [ 'from' => 'dispense_product', 'to' => 'finish' ], 'action_gotsurplus' => [ 'from' => 'dispense_product', 'to' => 'give_change' ], 'action_allpaid' => [ 'from' => 'give_change', 'to' => 'finish' ] ];
Here’s a real life example, because you can only go so far with imaginary coke machines.
This is from a mortgage company. Before granting a remortgage on a property, we need to check if the customer has owned the property for less than six months. If they had, then we had to find out why, and a letter had to be written to the mortgage lender. In some instances, the customer had to post signed documents back to the company.
Workflow diagram for 6 Month Proprietorship Check