Implementing Stateful Objects or State Machines
Problem
You want to implement a state machine or an object that operates in a number of different states, but don’t want to litter your code with a lot of conditionals.
Solution
In certain applications, you might have objects that operate differently according to some kind of internal state. For example, consider a simple class representing a connection:
class
Connection
(
object
):
def
__init__
(
self
):
self
.
state
=
'CLOSED'
def
read
(
self
):
if
self
.
state
!=
'OPEN'
:
raise
RuntimeError
(
'Not open'
)
(
'reading'
)
def
write
(
self
,
data
):
if
self
.
state
!=
'OPEN'
:
raise
RuntimeError
(
'Not open'
)
(
'writing'
)
def
open
(
self
):
if
self
.
state
==
'OPEN'
:
raise
RuntimeError
(
'Already open'
)
self
.
state
=
'OPEN'
def
close
(
self
):
if
self
.
state
==
'CLOSED'
:
raise
RuntimeError
(
'Already closed'
)
self
.
state
=
'CLOSED'
This implementation presents a couple of difficulties. First, the code
is complicated by the introduction of many conditional checks for the
state. Second, the performance is degraded because common operations
(e.g., read()
and write()
) always check the state before proceeding.
A more elegant approach is to encode each operational state as a
separate class and arrange for the Connection
class to delegate
to the state class. For example:
class
Connection
(
object
):
def
__init__
(
self
):
self
.
new_state
(
ClosedConnectionState
)
def
new_state
(
self
,
newstate
):
self
.
_state
=
newstate
# Delegate to the state class
def
read
(
self
):
return
self
.
_state ...
Get Implementing stateful objects or state machines in Python now with O’Reilly online learning.
O’Reilly members experience live online training, plus books, videos, and digital content from 200+ publishers.