The State Pattern in Python...

In the State Design Pattern, the same object behaves differently depending on the current state of the object.

For example, take the case of Chicken preparation.

When it is delivered, it remains in an uncleaned state. Hence the first task will be to clean it.

At that time if you call a specific method of the Chicken State, say, cook, it will behave differently (say maybe flash out a message that the chicken can't be cooked until it is properly cleaned and marinated). But the same cook method will cook the chicken once it is in the Marinated State. This time the "cook" method will properly cook the chicken and will flash out a different message - maybe like the Chicken is getting cooked - so have patience.

In the example, we have a ChickenState interface and then Mamma as the chef. The transition from one state to another is done at the end of the appropriate method of the interface at each state.

Enjoy the State Pattern written in written in Python

from __future__ import annotations
from abc import ABC, abstractmethod
import time

class Mamma():
    def __init__(self, state):
        self._state = state

    def get_state(self):
        return self._state

    def set_state(self, state):
        self._state = state

    def start_preparation(self):
        self._state.wash()
        self._state.marinate()
        self._state.cook()
        self._state.serve()

class State(ABC):
    @abstractmethod
    def wash(self):
        pass

    @abstractmethod
    def marinate(self):
        pass

    @abstractmethod
    def cook(self):
        pass

    @abstractmethod
    def serve(self):
        pass

class UncleanedState(State):
    def __init__(self, mamma):
        self._mamma = mamma

    def wash(self):
        print("Chicken is in the uncleaned state and is getting cleaned: next state will be cleaned state")
        time.sleep(1)
        self._mamma.set_state(CleanedState(self._mamma))

    def marinate(self):
        print("Chicken is in the uncleaned state... first clean it")
        pass

    def cook(self):
        print("Chicken is in the uncleaned state... first clean it")
        pass

    def serve(self):
        print("Chicken is in the uncleaned state... first clean it")
        pass

class CleanedState(State):
    def __init__(self, mamma):
        self._mamma = mamma

    def wash(self):
        print("Chicken is in the cleaned state... wash already done")
        pass

    def marinate(self):
        print("Chicken is in the cleaned state and is marinated. Next state will be marinate state")
        time.sleep(1)
        self._mamma.set_state(MarinateState(self._mamma))

    def cook(self):
        print("Chicken is in the cleaned state... first marinate it")
        pass

    def serve(self):
        print("Chicken is in the cleaned state... first marinate it")
        pass

class MarinateState(State):
    def __init__(self, mamma):
        self._mamma = mamma

    def wash(self):
        print("Chicken is in the marinated state... cleaning already done")
        pass

    def marinate(self):
        print("Chicken is in the marinated state... marination already done")
        pass

    def cook(self):
        print("Chicken is in the marinated state and being cooked. Next state will be cooked state")
        time.sleep(1)
        self._mamma.set_state(CookedState(self._mamma))

    def serve(self):
        print("Chicken is in the marinated state and being cooked. Only after cooking you can serve...")
        pass

class CookedState(State):
    def __init__(self, mamma):
        self._mamma = mamma

    def wash(self):
        print("Chicken has already been cooked")
        pass

    def marinate(self):
        print("Chicken has already been cooked")
        pass

    def cook(self):
        print("Chicken has already been cooked")
        pass

    def serve(self):
        print("Chicken is ready and is served: this is the last state")
        time.sleep(1)
        print("Guests are saying thank you for the meal")

if __name__ == '__main__':
    mamma = Mamma(None)
    mamma.set_state(UncleanedState(mamma))
    mamma.start_preparation()
0
Subscribe to my newsletter

Read articles from Somenath Mukhopadhyay directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Somenath Mukhopadhyay
Somenath Mukhopadhyay

To win is no more than this... To rise each time you fall...