State Pattern

Definition

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

Explanation

This pattern is used in computer programming to encapsulate varying behavior for the same routine based on an object’s state object. This can be a cleaner way for an object to change its behavior at runtime without resorting to large monolithic conditional statements.

Screencast

TypeScript Code

module State {
    interface IMusicPlayerState {
        start();
        stop();
        pauze();
    }

    class StoppedState implements IMusicPlayerState {
        constructor(private player: MusicPlayer) {
        }

        public start() {
            Output.WriteLine("Start playing.");
            this.player._state = new StartedState(this.player);
        }
        public stop() {
            Output.WriteLine("Already stopped!");
        }

        public pauze() {
            Output.WriteLine("I'm not started!");
        }
    }

    class StartedState implements IMusicPlayerState {
        constructor(private player: MusicPlayer) {
        }

        public start() {
            Output.WriteLine("Already started!");
        }
        public stop() {
            Output.WriteLine("Stopped playing.");
            this.player._state = new StoppedState(this.player);
        }
        public pauze() {
            Output.WriteLine("Pauzed playing.");
            this.player._state = new PauzedState(this.player);
        }
    }

    class PauzedState implements IMusicPlayerState {
        constructor(private player: MusicPlayer) {
        }

        public start() {
            Output.WriteLine("Continue playing.");
            this.player._state = new StartedState(this.player);
        }
        public stop() {
            Output.WriteLine("Stop playing!");
            this.player._state = new StoppedState(this.player);
        }
        public pauze() {
            Output.WriteLine("Already pauzed.");
        }
    }

    export class MusicPlayer {
        public _state: IMusicPlayerState;
        constructor() {
            this._state = new StoppedState(this);
        }

        public start() {
            this._state.start();
        }
        public stop() {
            this._state.stop();
        }
        public pauze() {
            this._state.pauze();
        }
    }
}

window.addEventListener("load", function () {
    var musicPlayer = new State.MusicPlayer();
    musicPlayer.stop();
    musicPlayer.start();
    musicPlayer.start();
    musicPlayer.pauze();
    musicPlayer.start();
    musicPlayer.stop();
});

Output