Player · contextcurrent = StoppedState
⏹ STOPPED
♪ Midnight Drive · Track 07
│ delegates
│ delegates
│ delegates
StoppedState
pressPlay() → start
pressStop() → ignore
PlayingState
pressPlay() → pause
pressStop() → stop
PausedState
pressPlay() → resume
pressStop() → stop
pressPlay() {
  switch (this.state) {
    case "STOPPED": startFrom(0);  state = "PLAYING"; break;
    case "PLAYING": pause();       state = "PAUSED";  break;
    case "PAUSED":  resume();      state = "PLAYING"; break;
  }
}
pressStop() { switch (this.state) { …same 3 cases again… } }
pressNext() { switch (this.state) { …and again… } }
+1 state = edit every method
One button, three behaviors
The glowing card is the player's current state object. Click ⏯ pressPlay() a few times — the same button starts, pauses, then resumes, because a different class answers each call.
The button never changes — the state object answering it does, and that object also picks the next state.