模式介绍
状态模式适用于状态变换的场景,比如我们Linux上的进程(有运行态、睡眠态、不可中断态、僵尸态等),tcp链接的四次挥手和三次握手也掺杂着状态的变换,而我们生活中例子也有很多,比如核酸检测点(预备营业,营业,准备关门,关门),植物(刚播种,发芽,开花,结果)。
状态模式中一个状态可能会从一个或者多个状态变换而来,这是需要我们写代码进行控制的,此外状态变换前和变换后往往可以放置钩子函数,比如进程转换为僵尸态的时候,要释放资源。
上代码
还是使用椰奶的例子,椰奶刚开始是空罐子,装满了,售卖,卖出,引用状态。
from state_machine import (State, Event, acts_as_state_machine,
after, before, InvalidStateTransition)
@acts_as_state_machine
class CoconutMilk:
"""椰奶对象保存椰奶的不同状态"""
empty = State(initial=True) # 空罐
full = State() # 装满了
sale = State() # 售卖状态
saleOut = State() # 卖出的状态
drinking = State() # 饮用的状态
fill_up = Event(from_states=(empty, drinking), to_state=full)
issued = Event(from_states=(full), to_state=sale)
workOff = Event(from_states=(sale), to_state=saleOut)
drink = Event(from_states=(full, saleOut), to_state=drinking)
def __init__(self, cm_uid):
self.cm_uid = cm_uid
@after('full')
def full_info(self):
print(f"我已经被装满了,可以售卖了")
@before('drinking')
def drink_info(self):
print(f"喝前请摇一摇")
def transition(cm, event, event_name):
try:
event()
except InvalidStateTransition as err:
print(f"Error: transition of {cm.cm_uid} from {cm.current_state} to {event_name} failed")
def state_info(cm):
print(f"state of {cm.cm_uid} : {cm.current_state}")
if __name__ == "__main__":
cm = CoconutMilk('cm_id_01')
transition(cm, cm.fill_up, 'full')
state_info(cm)