Motivation: An object’s behaviour changes substantially depending on its internal state, and managing this with conditionals scattered throughout the class becomes unwieldy.

Intent: Allow an object to alter its behaviour when its internal state changes, as if the object changed its class.

interface State {
    fun handle(doc: Document)
}
 
class DraftState : State {
    override fun handle(doc: Document) { doc.state = ReviewState() }
}
 
class ReviewState : State {
    override fun handle(doc: Document) { doc.state = PublishedState() }
}
 
class PublishedState : State {
    override fun handle(doc: Document) { /* already published */ }
}
 
class Document {
    var state: State = DraftState()
    fun advance() = state.handle(this)
}