THN Interview Prep

State (Behavioral)

Intent / problem it solves

Allow an object to alter its behavior when its internal state changes; object appears to change class. Replaces large conditional spaghetti with polymorphic state objects.

When to use / when NOT

Use for finite state machines: TCP connections, turnstiles, media players, workflow engines.

Avoid when two states and a boolean suffice; avoid state explosion without tables or diagrams.

Structure

Context delegates to state interface; concrete states transition context based on events.

Loading diagram…

Go example

package main

import "fmt"

type Turnstile struct {
	state GateState
}

type GateState interface {
	Coin(*Turnstile)
	Push(*Turnstile)
}

type LockedState struct{}

func (LockedState) Coin(gate *Turnstile) {
	gate.state = UnlockedState{}
	fmt.Println("unlock")
}

func (LockedState) Push(gate *Turnstile) { fmt.Println("blocked") }

type UnlockedState struct{}

func (UnlockedState) Coin(gate *Turnstile) { fmt.Println("thanks") }

func (UnlockedState) Push(gate *Turnstile) {
	gate.state = LockedState{}
	fmt.Println("lock")
}

func main() {
	gate := Turnstile{state: LockedState{}}
	gate.state.Coin(&gate)
	gate.state.Push(&gate)
}

JavaScript example

class PlayerContext {
  constructor() {
    this.state = new IdleState();
  }

  pressPlay() {
    this.state.onPlay(this);
  }

  transition(next) {
    this.state = next;
  }
}

class IdleState {
  onPlay(context) {
    console.log('start');
    context.transition(new PlayingState());
  }
}

class PlayingState {
  onPlay(context) {
    console.log('pause');
    context.transition(new IdleState());
  }
}

const player = new PlayerContext();
player.pressPlay();
player.pressPlay();

Interview phrase

“State replaces nested switches with objects—each state knows legal transitions, which keeps FSMs readable and testable.”

Map to LLD for workflow engines, game entities, or order lifecycles in LLD case studies.

Last updated on

Spotted something unclear or wrong on this page?

On this page