github地址:https://github.com/cheesezh/python_design_patternspython
用代碼模擬一天的工做狀態,上午狀態好,中午想睡覺,下午漸恢復,加班苦煎熬。git
hour = 0 work_finished = False def write_program(): if hour < 12: print("當前時間: {} 點, 上午工做,精神百倍".format(hour)) elif hour < 13: print("當前時間: {} 點, 餓了,午餐,犯困,午休".format(hour)) elif hour < 17: print("當前時間: {} 點, 下午狀態還能夠,繼續努力".format(hour)) elif work_finished == True: print("當前時間: {} 點, 收工,下班".format(hour)) elif hour < 21: print("當前時間: {} 點, 加班中,好累".format(hour)) else: print("當前時間: {} 點, 不行了,睡着了".format(hour)) hour = 9 write_program() hour = 10 write_program() hour = 12 write_program() hour = 13 write_program() hour = 14 write_program() hour = 17 work_finished = True # work_finished = False write_program() hour = 19 write_program() hour = 22 write_program()
當前時間: 9 點, 上午工做,精神百倍 當前時間: 10 點, 上午工做,精神百倍 當前時間: 12 點, 餓了,午餐,犯困,午休 當前時間: 13 點, 下午狀態還能夠,繼續努力 當前時間: 14 點, 下午狀態還能夠,繼續努力 當前時間: 17 點, 收工,下班 當前時間: 19 點, 收工,下班 當前時間: 22 點, 收工,下班
class Work(): def __init__(self): self.hour = 0 self.task_finished = False def write_program(self): if self.hour < 12: print("當前時間: {} 點, 上午工做,精神百倍".format(self.hour)) elif self.hour < 13: print("當前時間: {} 點, 餓了,午餐,犯困,午休".format(self.hour)) elif self.hour < 17: print("當前時間: {} 點, 下午狀態還能夠,繼續努力".format(self.hour)) elif self.work_finished == True: print("當前時間: {} 點, 收工,下班".format(self.hour)) elif self.hour < 21: print("當前時間: {} 點, 加班中,好累".format(self.hour)) else: print("當前時間: {} 點, 不行了,睡着了".format(self.hour)) work = Work() work.hour = 9 work.write_program() work.hour = 10 work.write_program() work.hour = 12 work.write_program() work.hour = 13 work.write_program() work.hour = 14 work.write_program() work.hour = 17 work.work_finished = True # work_finished = False work.write_program() work.hour = 19 work.write_program() work.hour = 22 work.write_program()
當前時間: 9 點, 上午工做,精神百倍 當前時間: 10 點, 上午工做,精神百倍 當前時間: 12 點, 餓了,午餐,犯困,午休 當前時間: 13 點, 下午狀態還能夠,繼續努力 當前時間: 14 點, 下午狀態還能夠,繼續努力 當前時間: 17 點, 收工,下班 當前時間: 19 點, 收工,下班 當前時間: 22 點, 收工,下班
單一職責原則
;開放-封閉原則
;狀態模式,當一個對象的內在狀態改變是容許改變其行爲,這個對象看起來像是改變了其類。[DP]github
狀態模式主要解決的是當控制一個對象狀態轉換的條件表達式過於複雜時的狀況。把狀態的判斷邏輯轉移到表示不一樣狀態的一系列類當中,能夠把複雜的判斷邏輯簡化。函數
from abc import ABCMeta, abstractmethod class State(): __metaclass__ = ABCMeta @abstractmethod def handle(self, context): pass class StateA(State): def handle(self, context): context.set_state(StateB()) class StateB(State): def handle(self, context): context.set_state(StateA()) class Context(): def __init__(self, state): self.state = state def set_state(self, state): self.state = state print("當前狀態: {}".format(self.state.__class__)) def request(self): self.state.handle(self) # 精髓 def main(): context = Context(StateA()) context.request() context.request() context.request() context.request() main()
當前狀態: <class '__main__.StateB'> 當前狀態: <class '__main__.StateA'> 當前狀態: <class '__main__.StateB'> 當前狀態: <class '__main__.StateA'>
狀態模式的好處是將與特定狀態相關的行爲局部化,而且將不一樣狀態的行爲分割開來。[DP]就是將特定的狀態相關的行爲都放入一個對象中,因爲全部與狀態相關的代碼都存在於某個ConcretState中,因此經過定義新的子類能夠很容易的增長新的狀態和轉換[DP]。這樣作的目的就是爲了消除龐大的條件分支語句,大的分支判斷會使得它們難以修改和擴展。狀態模式經過把各類狀態轉移邏輯分不到State的子類之間,來減小相互之間的依賴。設計
何時須要考慮使用狀態模式呢?當一個對象的行爲取決於它的狀態,而且它必須在運行時刻根據狀態改變它的行爲,就可使用狀態模式。另外,若是業務需求某項業務有多個狀態,一般都是一些枚舉常量,狀態的變化都是依靠大量的分支判斷語句來實現,此時應該考慮將每一種業務狀態定義爲一個State子類,這樣這些對象就能夠不依賴於其餘對象而獨立變化了,若是某天客戶需求改了,增長或減小業務狀態或改變狀態流程,都不是困難了。code
from abc import ABCMeta, abstractmethod class State(): __metaclass__ = ABCMeta @abstractmethod def write_program(self, work): pass class ForenoonState(State): def write_program(self, work): if work.hour < 12: print("當前時間: {} 點, 上午工做,精神百倍".format(work.hour)) else: work.set_state(NoonState()) work.write_program() class NoonState(State): def write_program(self, work): if work.hour < 13: print("當前時間: {} 點, 餓了,午餐,犯困,午休".format(work.hour)) else: work.set_state(AfternoonState()) work.write_program() class AfternoonState(State): def write_program(self, work): if work.hour < 17: print("當前時間: {} 點, 下午狀態還能夠,繼續努力".format(work.hour)) else: work.set_state(EveningState()) work.write_program() class EveningState(State): def write_program(self, work): if work.task_finished == True: work.set_state(RestState()) work.write_program() elif work.hour < 21: print("當前時間: {} 點, 加班中,好累".format(work.hour)) else: work.set_state(SleepingState()) work.write_program() class SleepingState(State): def write_program(self, work): print("當前時間: {} 點, 不行了,睡着了".format(work.hour)) class RestState(State): def write_program(self, work): print("當前時間: {} 點, 收工,下班".format(work.hour)) class Work(): def __init__(self, state): self.state = state self.hour = 0 self.task_finished = False def set_state(self, state): self.state = state def write_program(self): self.state.write_program(self) # 精髓 work = Work(ForenoonState()) work.hour = 9 work.write_program() work.hour = 10 work.write_program() work.hour = 12 work.write_program() work.hour = 13 work.write_program() work.hour = 14 work.write_program() work.hour = 17 work.work_finished = True # work_finished = False work.write_program() work.hour = 19 work.write_program() work.hour = 22 work.write_program()
當前時間: 9 點, 上午工做,精神百倍 當前時間: 10 點, 上午工做,精神百倍 當前時間: 12 點, 餓了,午餐,犯困,午休 當前時間: 13 點, 下午狀態還能夠,繼續努力 當前時間: 14 點, 下午狀態還能夠,繼續努力 當前時間: 17 點, 加班中,好累 當前時間: 19 點, 加班中,好累 當前時間: 22 點, 不行了,睡着了
假如老闆規定「員工必須在20點以前離開公司」,那麼只須要增長一個「強制下班狀態」,而後改動一下「傍晚工做狀態」就能夠了。而這是不影響其餘狀態的代碼的。orm