State Pattern

Programming application always involves dealing with a state of application at any point in time. State allows us to predict what application is going to behave like in certain point in time under certain inputs. Unless you are writing HTML code, which is stateless, you will get to deal with multiple states, and multiple logical states for that matter, i.e. those that are part of the program logic rather than application life cycle.

One of the most common techniques is to implement various states is to allocate instance variables for those states. For example, we can have a game where a player must shoot a target. This game can have a state like TARGET_IS_SHOT = 0 until the player hits it which will make it change its value to 1. It is an easy and straightforward approach to solve the problem of state in our application.

However, there are many cases where this approach wouldn’t fulfill our requirements. What if you want to add another state to an application? OK, we could do that. But then another one, and another one, and so on. What we would need to do is to go in our target class and modify it. That is too much maintenance and very little flexibility on behalf states. Is there a way to implement it using OOP approach? Totally! It is called the State Pattern.


The State Pattern

allows an object to alter its behavior when ts internal state changes. The object will appear to change its class.


There are several important things that happen when we use the State Pattern:

  • We create a State interface that contains methods for every action in our application
  • We will implement a State class for every state that we need. Each of these classes will take care of a particular behavior in a particular state.
  • We will also remove all conditional code in those classes, thus delegating the work to them.
// Example in Java
// Source: https://en.wikipedia.org/wiki/State_pattern
interface State {
    void writeName(StateContext context, String name);
}

class LowerCaseState implements State {
    @Override
    public void writeName(StateContext context, String name) {
        System.out.println(name.toLowerCase());
        context.setState(new MultipleUpperCaseState());
    }
}

class MultipleUpperCaseState implements State {
    /* Counter local to this state */
    private int count = 0;

    @Override
    public void writeName(StateContext context, String name) {
        System.out.println(name.toUpperCase());
        /* Change state after StateMultipleUpperCase's writeName() gets invoked twice */
        if(++count > 1) {
            context.setState(new LowerCaseState());
        }
    }
}

class StateContext {
    private State state;
    
    public StateContext() {
        state = new LowerCaseState();
    }

    /**
     * Set the current state.
     * Normally only called by classes implementing the State interface.
     * @param newState the new state of this context
     */
    void setState(State newState) {
        state = newState;
    }

    public void writeName(String name) {
        state.writeName(this, name);
    }
}

public class StateDemo {
    public static void main(String[] args) {
        StateContext context = new StateContext();

        context.writeName("Monday");
        context.writeName("Tuesday");
        context.writeName("Wednesday");
        context.writeName("Thursday");
        context.writeName("Friday");
        context.writeName("Saturday");
        context.writeName("Sunday");
    }
}

By accomplishing these steps we end up following several good OOP principles. We localize the behavior of each state in its own class, thus making them keep their responsibilities down to one. Removal of conditionals makes our code more readable and easily maintainable. We closed each of those classes for modification, and left the code to be extensible.

State Pattern allows you to make application with different states, while utilizing the best that OOP has to offer, making it easy to maintain and extend.

Leave a comment