Finite State Machines

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.

Workflow diagram for a coke machine

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.

PHP Libraries

I’m using a FSM library written by Yohan Giarelli to implement statefulness for PHP classes. Symfony also has a workflow component which does much the same thing.

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'
	]
];

Real-life example

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