State Pattern - Example - Java

Java

The state interface and two implementations. The state's method has a reference to the context object and is able to change its state.

interface Statelike { /** * Writer method for the state name. * @param STATE_CONTEXT * @param NAME */ void writeName(final StateContext STATE_CONTEXT, final String NAME); } class StateA implements Statelike { /* (non-Javadoc) * @see state.Statelike#writeName(state.StateContext, java.lang.String) */ @Override public void writeName(final StateContext STATE_CONTEXT, final String NAME) { System.out.println(NAME.toLowerCase); STATE_CONTEXT.setState(new StateB); } } class StateB implements Statelike { /** State counter */ private int count = 0; /* (non-Javadoc) * @see state.Statelike#writeName(state.StateContext, java.lang.String) */ @Override public void writeName(final StateContext STATE_CONTEXT, final String NAME) { System.out.println(NAME.toUpperCase); // Change state after StateB's writeName gets invoked twice if(++count > 1) { STATE_CONTEXT.setState(new StateA); } } }

The context class has a state variable that it instantiates in an initial state, in this case StateA. In its method, it uses the corresponding methods of the state object.

public class StateContext { private Statelike myState; /** * Standard constructor */ public StateContext { setState(new StateA); } /** * Setter method for the state. * Normally only called by classes implementing the State interface. * @param NEW_STATE */ public void setState(final Statelike NEW_STATE) { myState = NEW_STATE; } /** * Writer method * @param NAME */ public void writeName(final String NAME) { myState.writeName(this, NAME); } }

The test below shows also the usage:

public class TestClientState { public static void main(String args) { final StateContext SC = new StateContext; SC.writeName("Monday"); SC.writeName("Tuesday"); SC.writeName("Wednesday"); SC.writeName("Thursday"); SC.writeName("Friday"); SC.writeName("Saturday"); SC.writeName("Sunday"); } }

According to the above code, the output of main from TestClientState should be:

monday TUESDAY WEDNESDAY thursday FRIDAY SATURDAY sunday

Read more about this topic:  State Pattern, Example