State: Delegate Behavior by Current State
A draft may be published, while an already published document may reject the same request. Scattered state checks make rules easy to miss. State delegates behavior according to an object’s current stage.
Consider behavior and transitions together
class Draft:
def publish(self, document):
document.state = Published()
return "published"
class Published:
def publish(self, document):
return "already published"
class Document:
def __init__(self):
self.state = Draft()
def publish(self):
return self.state.publish(self)
document = Document()
print(document.publish())
print(document.publish())
The outputs are published and already published. The first request reaches Draft, which handles it and changes the context to Published. The next request follows Published’s rules.
Document allowed transitions in a table or diagram too. This example allows only draft → published. Unpublishing needs explicit conditions and responsibility for returning to draft.
Similar shape, different purpose from Strategy
Strategy emphasizes interchangeable algorithms. State emphasizes the current stage and its allowed actions. Two simple states may be clearer as an enum and conditional. Compare the benefits of separation as state-specific rules grow.
Check your understanding
What happens if the state changes to Published before an actual publication operation fails?
Show explanation
Later requests may treat an unpublished document as published. Coordinate operation success with state transitions. External storage and concurrent requests need additional consistency mechanisms.