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)
}