Think of a state machine as a traffic light. When you are waiting at the red signal, the other two lights (or states) are not active. But, as soon as the green light turns on, the red turns off and the state changes. So, we have our signal to move.
If you are somebody standing at the signal, you don’t need to know what type of state machine is used to operate lights. But, as a programmer writing computational code, it is necessary to know a lot about state machines.
In this article, we will discuss exactly the same, read on…
What is State Machine?
A state machine is a problem-solving pattern that helps resolve different state switching mechanisms in a given system.
In some situations arising at the time of solution making, there are various activities that are complex and they depend on both the previous and next state to perform certain actions. This type of issue is handled by various methods like nested if-else loops and multi-level switches. When we achieve that, we experience maintainability issues and cognitive comprehension challenges (which make the code difficult to understand).
With the help of state machines, we can resolve similar situations with clean, scalable, and flexible code.
Let’s explore an example to better understand the situation:
Room Switching Mechanism for Home
With the disruption of IoT space, home automation has become common and digitization of home utilities is drastically increasing. One of the problems faced during optimization is the utilization of power. When someone is walking around the house, isn’t it better to track and manage utilities based on their presence?
In this situation, a state machine helps judge the current and past states of the user.
Here is the list of state and expected activities that can be performed when a person is in different locations in their home.
- State Main Door: If the user is present on the front main door, the application needs to unlock the door. After the user exits from the main door area, the door needs to be locked again.
- State Hall: If the user enters the hall, the application needs to turn on the lights and fans in the hall. When the user leaves the hall, the lights and fans should be turned off.
- State Master Bedroom: If the user enters the master bedroom, the application needs to turn on the lights, fans, and AC in the room. When the user leaves the master bedroom, these devices need to be turned off.
- State Kids Bedroom: If the user enters the kids’ bedroom, the application needs to turn on the lights, fans, and AC in the room. When the user leaves the kid's bedroom, these devices need to be turned off.
- State Kitchen: If the user enters the kitchen, the application needs to turn on the lights and other necessary appliances in the kitchen. When the user leaves the kitchen, these devices need to be turned off.
In the above example of home design, the possibility of user presence at the main door is two ways.
- First, from outside the home entrance.
- Second, from inside the hall.
Similarly, there are four ways to enter the hall, from:
- The master bedroom
- The kids’ bedroom
- The kitchen
- The main door
There are two ways to enter the master bedroom, from:
- The hall
- The kids’ bedroom
There are two ways to enter into kids’ bedroom, from:
- The master bedroom
- The hall
There is only one entry point to the kitchen, from the hall.
In a state machine, we have two steps.
- The first step is to act before leaving the existing state.
- The second step is to act so that we can enter a new state.
It is also easy to expand in state machines if there are any new stages in the future. The only requirement that may arise here is to write each state’s entry and exit points. In this case, we don’t even need to understand or remember the previous state's functionality.
To explain better in terms of code, here is an example:
enum State {
case maindoor
case hall
case masterBedroom
case kidsBedroom
case kitchen
}
var currentState: State = .maindoor
func updateState(newState: State) {
switch currentState {
case .maindoor:
// close and lock the main door
break
case .hall:
// turn off all the elements in the hall
break
case .masterBedroom:
// turn off all the elements in the master bedroom
break
case .kidsBedroom:
// turn off all the elements in the kid’s bedroom
break
case .kitchen:
// turn off all the elements in the kitchen
break
}
switch newState {
case .maindoor:
// unlock and open the main door
break
case .hall:
// turn on all the elements in the hall
break
case .masterBedroom:
// turn on all the elements in the master bedroom
break
case .kidsBedroom:
// turn on all the elements in the kid’s bedroom
break
case .kitchen:
// turn on all the elements in the kitchen
break
}
currentState = newState
}
Summary
With the help of a state machine, we are able to change the states of action according to inputs. A state, on the other hand, is the execution of this transition from one status to another. Without these actions, it is not possible to easily transition from one state to another. Therefore, the knowledge of state machines is imperative for clean and agile code.