设计模式十五:状态模式
什么是状态模式
状态模式就是状态机模式,状态机是一个抽象机器,两个关键部分:状态和转换。
状态:系统的当前状况。
转换:从一个状态转换到另一个状态,因某个事件或条件的触发而开始。
通常在一次转换发生之前或之后会执行一个或一组动作。
注意:一个状态机在一个特定时间点只能有一个激活状态
可用模块:state_machine
典型案例
电梯运行,电梯有三个状态,停止,上行,下行。
实例代码
from state_machine import State,Event,acts_as_state_machine,after,before,InvalidStateTransition
@acts_as_state_machine # 使用修饰器 修饰是第一步
class Process:
# 定义状态
created = State(initial=True) # 定义状态机的初始状态
waiting = State()
running = State()
terminated = State()
blocked = State()
swapped_out_waiting = State()
swapped_out_blocked = State()
# 定义状态转换
wait = Event(from_states = (created,running,blocked,
swapped_out_waiting),to_state=waiting)
run = Event(from_states = waiting, to_state = running)
terminate = Event(from_states=(running,swapped_out_blocked),to_state=terminated)
block = Event(from_states = (running,swapped_out_blocked),to_state=blocked)
swap_wait = Event(from_states=waiting,to_state=swapped_out_waiting)
swap_block = Event(from_states = blocked,to_state = swapped_out_blocked)
def __init__(self,name):
self.name = name
@after('wait') # 状态转换之后的执行动作
def wait_info(self):
print('{} entered waiting mode'.format(self.name))
@after('run')
def run_info(self):
print('{} running'.format(self.name))
@before('terminate') # 状态转换之前的执行动作
def terminate_info(self):
print('{} terminated'.format(self.name))
@after('block')
def block_info(self):
print('{} is blocked'.format(self.name))
@after('swap_wait')
def swap_wait_info(self):
print('{} is swapped out and waiting'.format(self.name))
@after('swap_block')
def swap_block_info(self):
print('{} is swapped out and blocked'.format(self.name))
def transition(process,event,event_name): # 尝试执行event
try:
event()
except InvalidStateTransition as err:
print('Error: transition of {} from {} to {} failed'.format(process.name,process.current_state,event_name))
def state_info(process): # 显示当前信息
print('state of {}:{}'.format(process.name,process.current_state))
def main():
RUNNING = 'running'
WAITING = 'waiting'
BLOCKED = 'blocked'
TERMINATED = 'terminated'
p1,p2 = Process('process1'),Process('process2')
[state_info(p) for p in (p1,p2)]
print()
transition(p1,p1.wait,WAITING)
transition(p2,p2.terminate,TERMINATED)
[state_info(p) for p in (p1,p2)]
print()
transition(p1,p1.run,RUNNING)
transition(p2,p2.wait,WAITING)
[state_info(p) for p in (p1,p2)]
print()
transition(p2,p2.run,RUNNING)
[state_info(p) for p in (p1,p2)]
print()
[transition(p,p.block,BLOCKED) for p in (p1,p2)]
[state_info(p) for p in (p1,p2)]
print()
[transition(p,p.terminate,TERMINATED) for p in (p1,p2)]
[state_info(p) for p in (p1,p2)]
if __name__ == "__main__":
main()