1. 程式人生 > >Python:有限狀態機小用例

Python:有限狀態機小用例

#   _*_ coding:utf-8 _*_
from random import randint
from time import sleep

__author__ = 'admin'

'''
    23種設計模式之狀態模式:有限狀態機
    下面介紹了燈的三種狀態:
    1.開著
    2.滅著
    3.壞了
    其中"壞了"的狀態下,若是修好了,必然進入滅著的狀態
'''

#   Light類
class Light(object):
    def __init__(self, name):
        self.name = name
        self.state = ""
        self.fsm = None

    #   開燈方法
    def lightOn(self):
        #   列印語句代替行為
        print("燈亮著[%s]" % self.name)

    #   關燈方法
    def lightOff(self):
        print("燈滅著[%s]" % self.name)

    #   壞燈方法
    def lightBroken(self):
        print("燈壞了[%s]" % self.name)

    #   繫結狀態機
    def bind(self, state, fsm):
        self.state = state
        self.fsm = fsm


# 定義狀態
class State(object):
    def exec(self, obj):
        pass

    def exit(self, obj):
        pass


# 定義開燈狀態,繼承State(這裡就是寫進入該狀態時該幹那些事情,退出該狀態時該幹那些事情)
class OnState(State):
    #   進入還狀態無非就是,將燈做開啟操作
    def exec(self, obj):
        obj.lightOn()

    #   退出該狀態,無非就是,將燈做關閉操作
    def exit(self, obj):
        obj.lightOff()


# 定義關燈狀態,繼承State
class OffState(State):
    def exec(self, obj):
        obj.lightOff()

    def exit(self, obj):
        obj.lightOn()


# 定義壞燈狀態,繼承State
class BrokenState(State):
    def exec(self, obj):
        obj.lightBroken()

    def exit(self, obj):
        obj.lightOff()


#   狀態機管理器,這裡主要做一些轉換狀態的操作
class StateMachine(object):
    def __init__(self):
        #   指明訊號和各狀態的對應關係
        self.states = {0: OnState(), 1: OffState(), 2: BrokenState()}

    #   通過給定的state返回其對應的狀態物件
    def getFsm(self, state):
        return self.states[state]

    #   切換物件的狀態
    def changeState(self, NewState, objs):
        for obj in objs:
            #   如果新產生的訊號和物件原本的執行狀態對應的訊號一致的話
            if NewState == obj.state:
                #   保持原狀態
                fsm = self.getFsm(obj.state)
                fsm.exec(obj)
            else:
                #   先退出舊狀態
                old_fsm = self.getFsm(obj.state)
                old_fsm.exit(obj)
                #   執行新狀態
                obj.state = NewState
                new_fsm = self.getFsm(NewState)
                new_fsm.exec(obj)


def run():
    sm = StateMachine()
    lights = []
    names = ['red', 'green', 'yellow']
    #   物件的製造機
    for i in range(1):
        l = Light(names[i])
        l.bind(0, sm.getFsm(0))
        lights.append(l)
    while True:
        #   生成新的訊號
        state = randint(0, 2)
        sm.changeState(state, lights)
        sleep(2)
run()