State

Intent

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

Structure of design pattern

State pattern structure

Pseudocode

// Common interface for all states.
abstract class State is
    field player: Player

    // Context passes itself through the state constructor. This may help a
    // state to fetch some useful context data if needed.
    constructor State(player) is
        this.player = player

    abstract method onLock(event)
    abstract method onPlay(event)
    abstract method onNext(event)
    abstract method onPrevious(event)


// Concrete states provide the special implementation for all interface methods.
class LockedState is
    method onLock(event) is
        if (player.playing)
            player.changeState(new PlayingState(player))
        else
            player.changeState(new ReadyState(player))

    method onPlay(event) is
        Do nothing.

    method onNext(event) is
        Do nothing.

    method onPrevious(event) is
        Do nothing.


// They can also trigger state transitions in the context.
class ReadyState is
    method onLock(event) is
        player.changeState(new LockedState(player))

    method onPlay(event) is
        player.startPlayback();
        player.changeState(new PlayingState(player))

    method onNext(event) is
        player.nextSong();

    method onPrevious(event) is
        player.previousSong();


class PlayingState is
    method onLock(event) is
        player.changeState(new LockedState(player))

    method onPlay(event) is
        player.stopPlayback();
        player.changeState(new ReadyState(player))

    method onNext(event) is
        if (event.doubleclick)
            player.nextSong();
        else
            player.fastForward(5)

    method onPrevious(event) is
        if (event.doubleclick)
            player.previous();
        else
            player.previousSong(5)


// Player acts as a context.
class Player is
    field state: State
    field UI, volume, playlist, currentSong

    constructor Player(player) is
        this.state = new ReadyState(this)
        UI = new UserInterface()

        // Context delegates handling user's input to a state object. Naturally,
        // the outcome will depend on what state is currently active, since all
        // states can handle the input differently.
        UI.lockButton.onClick(state.onLock)
        UI.playButton.onClick(state.onNext)
        UI.nextButton.onClick(state.onNext)
        UI.prevButton.onClick(state.onPrevious)

    // State may call some service methods on the context.
    method startPlayback() is
        // ...
    method stopPlayback() is
        // ...
    method nextSong() is
        // ...
    method previousSong() is
        // ...
    method fastForward(time) is
        // ...
    method rewind(time) is
        // ...

Implementations in Different Programming Languages

Java