What is a State Machine ?
an abstract machine that can be in exactly one of a finite number of states at any given time. The FSM can change from one state to another in response to some external 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 conditions for each transition.
It is a way to program a model so that it is at one particular state at any moment.
The world is filled with state machines which we can see anywhere in our daily usage. Below are few
- Road Traffic Signal Red -> Yellow -> Green
- Coffee Vending Machine
- E-commerce Portal Ordering
- Online Trip Booking
- Many Jobs
Implementing State Machines In Java
There are many ways in which we can implement state machines. In the Java world itself, we have many libraries using which we can model these states
* [Spring State Machine](https://projects.spring.io/spring-statemachine/)
We can also implement them using a standard `State Design pattern` [example] https://www.journaldev.com/1751/state-design-pattern-java)
What if we don’t want to add any external dependencies?
What if we want to have a simple state machine and control it via our own logic?
State Machines Using Enums in Java
Many of us would have used Uber or Ola at-least once. Let’s try implementing the trip booking state machine using Java Enums
What are the ideal states in trip booking?
- Trip Booked
- Driver Assigned
- Driver Reached
- Trip Started
- Trip Ended
The above enum can be used across our application for maintaining the state of the trip. Even in a database, this can be used by using the string value of the enum. Example TripStates.TRIPCREATED.name()
Now we have implemented the state machine but how to ensure proper state transition happens. One simple way is to include a function within the enum and check it across whenever we are trying to change the state of a trip
The above function needs to be called wherever state changes need to happen. This helps in moving states in a forward manner.
But there is a problem with this. We will be able to move a trip from a trip created to a trip started. The above implementation might not solve the real constraint we would like to introduce like a trip cannot be marked as started without marking as reached.
How can we achieve this with just enum?
Java Enums can have additional fields to it. We can leverage that to solve this.
If you look we are maintaining validFromStates in order to easily expand this to other cases where a trip can end even from different states. Example: CustomerNotReachable etc..
The above is a simple implementation that can be used. But if we wanted to have more logic within these state transitions we can still leverage but we need to hook the above model with other design patterns.
Cross Posted from Personal Blog