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.”
Related LLD case studies
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?