Finite state machines (FSM) can be a useful tool to have as a developer. They are abstract machines that can be in one of many possible states at a given time. FSM can change from one state to another in response to external input (called a transition).
We can observe FSM in many devices and machines. Examples of these can include traffic lights, elevators, and even some apps on our mobile devices. In some beginning compiler courses, students will write a finite state machine to handle lexical analysis.
We define FSM with the following characteristics.
- A set of states
- An initial state
- Sets of conditions for transitions from each state
- An optional subset of states that represent the completion
As a developer, we can use FSM to make it easier to express certain types of business logic. One way we can use one is to control the states of controls on a form. Depending on the state of our FSM, we can enable and disable controls as needed. As an example, let’s say we have the following FSM for a sales order form.
In this FSM, we have the following states.
- New (our initial state)
- Ready (indicates the order is ready for processing)
- Warehouse (indicates that the order is ready for warehouse personnel to process)
- Packed (indicates the order was picked and packed in the warehouse)
- Shipped (indicates the order was shipped to the customer and is ready for accounts receivable to invoice)
- Complete (indicates that the order is ready for accounts receivable to invoice)
- Invoice (indicates an invoice was generated and is the completion state)
Within this FSM, we can see the following transitions.
- Click “Complete order” button (new à ready)
- Inventory items (ready à warehouse)
- Non-inventory items (ready à complete)
- Warehouse reports order packed (warehouse à packed)
- Warehouse reports order shipped (warehouse à shipped)
- Invoice order (complete à invoiced and shipped à invoiced)
Assume on our sales order form, we have two buttons “Complete order” and “Invoice order.” The “Complete order” button triggers the Click “complete order” button transition. Similarly, the “Invoice order” button triggers the Invoice order transition.
When a salesperson creates the sales order, the order will have a state of New; our initial state. When the sales order is in the New state, the “Complete order” button will need to be active. The reason is that the Click “complete order” button transition is a valid transition in this state. The “Invoice order” button will not be active as Invoice order is not a valid transition.
Once in the Ready state, both buttons will not be active as neither of the transitions they trigger is valid. In this example, the Ready state can be a signal to an automated process that determines if the sales order needs routing to the warehouse (Inventory items transition) or accounts receivable (non-inventory items transition).
Similarly, both buttons will not be active when the sales order is in the Warehouse or Packed states. Warehouse personnel is processing the order and the buttons are not applicable until they finish. When the warehouse ultimately ships the order, the state will transition to Shipped.
It is when our order enters the Complete or Shipped states will there be a change in the sales order form. In these states, the “Invoice order” button will be active because the transition it triggers is valid for both of those states. The New button will remain inactive.
Once someone clicks the “Invoice order” button, the order will transition to the Invoice state. Since the Invoiced state is the completion state, neither button will be active.