Java design pattern State

Today we will look at another Java design pattern from the category of behavioural patterns – State. Java design patterns in this category deal with the interaction between objects and their responsibility.

What is the State design pattern?

State is a design pattern that allows an object to change its behaviour when its internal state changes. In the pattern, we create objects that represent individual states, and a context object whose behaviour changes depending on the state of the object.

For a better understanding, let’s imagine a simple ticket machine. Its behaviour varies depending on the stage of the purchase process (specific state) it is in (e.g. ticket selection, payment, confirmation). Implementing this automated process using the State design pattern would make the code clearer by breaking the business logic of each phase into separate states.

What problem does the State pattern solve?

The State pattern solves the problem of an object behaving differently depending on its current state. It allows you to define different states and transitions between them, while keeping the state logic separate from the main object logic. This concept is similar to that of finite state machines (FSMs). The behaviour of each state is defined independently of the other states, and adding new states should not affect the behaviour of existing states.

Example of a State implementation in Java

The practical use of the State design pattern is illustrated by the example of traffic lights with red, orange and green states that control road traffic.

TrafficLightState.java

package designpatterns;

public interface StavSemaforu {
    void vykonat();
}

The TrafficLightState is the interface that defines the execute() method. Each traffic light state (red, orange, green) implements this interface and provides its own implementation of execute().

Red.java, Orange.java, Green.java

package designpatterns;

public class Cervena implements StavSemaforu {
    @Override
    public void vykonat() {
        System.out.println("Svetlo na semafore sa preplo na červenú - premávka sa zastavila.");
    }
}

public class Oranzova implements StavSemaforu {
    @Override
    public void vykonat() {
        System.out.println("Svetlo na semafore sa preplo na oranžovú - čaká sa na zmenu.");
    }
}

public class Zelena implements StavSemaforu {
    @Override
    public void vykonat() {
        System.out.println("Svetlo na semafore sa preplo na zelenú - premávka sa rozbieha.");
    }
}

Red, Orange and Green are implementations of the TrafficLightState interface. Each of these classes represents one particular traffic light state and provides its own implementation for execute().

TrafficLights.java

package designpatterns;

// Kontext, ktory prepina stavy
public class Semafor {
    private StavSemaforu stav;

    public Semafor() {
        this.stav = new Oranzova();
    }

    public void prepnut(StavSemaforu novyStav) {
        this.stav = novyStav;
    }

    public void vykonat() {
        stav.vykonat();
    }
}

Traffic Lights is a class that represents a context where traffic light states change. In this case, the Traffic Lights will be initialized to orange. It has a switch() method that changes the current traffic light state to the specified new state. It also has an execute() method that executes the current state of the traffic lights.

Main.java

import designpatterns.Cervena;
import designpatterns.Oranzova;
import designpatterns.Semafor;
import designpatterns.Zelena;

public class Main {
    public static void main(String[] args) {
        // Semafor je na zaciatku inicializovany na stav oranzova.
        Semafor semafor = new Semafor();
        semafor.vykonat();
        semafor.prepnut(new Cervena());
        semafor.vykonat();
        semafor.prepnut(new Oranzova());
        semafor.vykonat();
        semafor.prepnut(new Zelena());
        semafor.vykonat();
    }
}

In the Main class we simulate the operation of traffic lights. We create an instance of the traffic lights, initially in the orange state. We then change the state of the lights using the switch() method and then call the execute() method, which handles the business logic defined for that state.

The output of this example is:

Sample output for Java design pattern State

Conclusion

The State pattern is useful when we have defined a finite number of states for an object to pass through, and we need to perform some action when its internal state changes.

We have prepared the files with the above example in the form of code that you can run directly in Java. You can download the Java State code here.

If you’re a Java developer looking for work, check out our employee benefits and respond to our job offers!

About the author

Jozef Wagner

Java Developer Senior

Viac ako 10 rokov programujem v Jave, momentálne pracujem v msg life Slovakia ako Java programátor senior a pomáham zákazníkom implementovať ich požiadavky do poistného softvéru Life Factory. Vo voľnom čase si rád oddýchnem v lese, prípadne si zahrám nejakú dobrú počítačovú hru.

Let us know about you