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