I would like to learn GoF design patterns in Python.
The State pattern is a type of behavioral design pattern used in programming. This pattern is used to represent the state of an object. It's a clean way to work with objects that partially change their type at runtime.
UML class and sequence diagram UML class diagram (The above is quoted from Wikipedia)
In the State
pattern, it seems that a thing called" state "is expressed by a class.
It is possible to share the state-dependent behavior with the ConcreteState
role here.
However, when using the State
pattern, it is important to note that ** who should manage the state transition **.
(If you leave the state transition to the role of ConcreteState
, the dependency between classes will be deepened.)
Actually, I would like to run a sample program that utilizes the State pattern and check the following behavior. Here, imagine "Visualization of startup status by operating a personal computer" </ font>.
--When you start your computer, the operating status will be "running". --When you stop your computer, the operating status becomes "shutdown". --When you restart your computer, the operating status will change to "running".
In the sample program, specify ** first argument: first computer operation **, ** second argument: second computer operation **.
The operating state first becomes "running" when the computer is started, and then becomes "shutdown" when the computer is stopped.
$ python Main.py start stop
###PC,[start]To do
***The computer is running
###The personal computer[running]Is now in operation
... sleep 5 second
###PC,[stop]To do
***The computer is stopped
###The operating status of the personal computer is[shutdown]became
The operating state first becomes "running" when the computer is started, and then it becomes "running" again when the computer is restarted.
$ python Main.py start restart
###PC,[start]To do
***The computer is running
###The personal computer[running]Is now in operation
... sleep 5 second
###PC,[restart]To do
***The computer will start restarting
***The computer is running
###The operating status of the personal computer is[running]became
With the above, the sample program worked as expected.
Similar code has been uploaded to the Git repository. https://github.com/ttsubo/study_of_design_pattern/tree/master/State
--Directory structure
.
├── Main.py
└── state
├── __init__.py
├── context.py
└── state.py
The State
role is meant to represent a state. Defines an interface that behaves differently for each state.
In the sample program, the State
class serves this role.
state/state.py
from abc import ABCMeta, abstractmethod
class State(metaclass=ABCMeta):
@abstractmethod
def handle(self):
pass
The ConcreteState
role represents a specific individual state.
Concretely implement the interface defined by the State
role.
In the sample program
--ConcreteStateBooting
class
--ConcreteStateRun
class
--ConcreteStateShutDown
class
--ConcreteStateRestart
class
However, I will try this role.
state/state.py
class ConcreteState(State):
def __init__(self, state):
self.state = state
def getConcreateState(self):
return self.state
class ConcreteStateBooting(ConcreteState):
def __init__(self, state):
super(ConcreteStateBooting, self).__init__(state)
def handle(self, context):
print("***The computer is running")
context.setState(ConcreteStateRun("running"))
class ConcreteStateRun(ConcreteState):
def __init__(self, state):
super(ConcreteStateRun, self).__init__(state)
def handle(self, context):
print("***The computer is in operation")
class ConcreteStateShutDown(ConcreteState):
def __init__(self, state):
super(ConcreteStateShutDown, self).__init__(state)
def handle(self, context):
print("***The computer is stopped")
class ConcreteStateRestart(ConcreteState):
def __init__(self, state):
super(ConcreteStateRestart, self).__init__(state)
def handle(self, context):
print("***The computer will start restarting")
context.setState(ConcreteStateBooting("booting"))
context.handle()
The Context
role holds an object for the ConcreteState
role that represents the current state.
In the sample program, the Context
class serves this role.
state/context.py
class Context(object):
def __init__(self, stateObj):
self.state = stateObj
def setState(self, obj):
self.state = obj
def handle(self):
self.state.handle(self)
def getState(self):
return self.state.getConcreateState()
In the sample program, the startMain
method serves this role.
Main.py
import sys
import time
from state.context import Context
from state.state import ConcreteStateBooting, ConcreteStateRun, ConcreteStateShutDown, ConcreteStateRestart
def setConcreteState(operation):
if operation == "start":
return ConcreteStateBooting("booting")
elif operation == "stop":
return ConcreteStateShutDown("shutdown")
elif operation == "restart":
return ConcreteStateRestart("restart")
def startMain(initial_operation, change_operation):
obj = Context(setConcreteState(initial_operation))
print("###PC,[{0}]To do".format(initial_operation))
obj.handle()
print("###The personal computer[{0}]Is now in operation".format(obj.getState()))
print("")
print("... sleep 5 second")
print("")
time.sleep(5)
obj.setState(setConcreteState(change_operation))
print("###PC,[{0}]To do".format(change_operation))
obj.handle()
print("###The operating status of the personal computer is[{0}]became".format(obj.getState()))
if __name__ == "__main__":
startMain(sys.argv[1], sys.argv[2])
-Design pattern in Python ~ Py design ~ / State pattern
Recommended Posts