🐍 State Pattern in Python

📗 Design patterns are conventional solutions to common challenges in software development using Object-oriented programming. Learn to implement state pattern and finite state machines using Python.

Finite State Machine

Let's define a finite state machine (FSM) before moving on to the state design pattern. It is well known that the concepts of state patterns and finite-state machines have a close relationship. An FSM is something that behaves differently depending on its internal state. In computer programming, the behavior of an object in an application varies depending on its state. A switch and a lightbulb are simple examples of FSM. "ON" and "OFF" are the two possible states of the light bulb. To change the state of the bulb 'ON' or 'OFF', simply flip the switch. Transition is the process of moving from one state to another. Transition is affected by several factors. In the case of the light bulb, it is dependent on the input from the switch. The state diagram, which is shown below, graphically depicts the states and transitions.

We can implement the state machine using any programming language. Depending on a few factors, our code behaves differently. You can implement the preceding light bulb example as follows:

class LightBulb:
  _state = 'OFF'    # initial state of bulb

  def onOff(self, switch):
    if switch == 'ON':
        self._state = 'ON'
    elif switch == 'OFF':
        self._state = 'OFF'
    else:
        continue          # if we get wrong input

For small systems, such as the one described above, the code appears to be straightforward and simple. However, if there are many states and transitions, our code will get flabby with conditional statements. The code becomes more extensive, and it won't be easy to maintain the application. If you want to add additional states or transitions to the program, you'll have to change the entire code base. You can use the State Design Pattern in these cases.

State Pattern

It is a behavioral design pattern. You can use the state pattern to implement state-specific behavior in which objects can change their functionality at runtime. You can use it to avoid using conditional statements when changing an object's behavior based on its state. In the state pattern, you should encapsulate different states in separate State classes. The original class keeps a reference to a state object based on its current state rather than using conditional statements to implement state-dependent functionality.

UML Diagram

1) Context - it is the original class of our application. It maintains a reference to one of the concrete states on which its behavior depends. It also has a method to modify the internal state.

2) State interface - All supported states share the same state interface. Only the state interface allows Context to communicate with state objects. Context can only communicate with state objects via the state interface.

3) Concrete states - For each state, these objects implement the 'State' interface. These are the main objects which contain the state-specific methods.

How does it work?

20