Python設計模式中的狀態(tài)模式你了解嗎
更新時間:2022年02月15日 10:35:43 作者:范桂颶
這篇文章主要為大家詳細介紹了Python設計模式中的狀態(tài)模式,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
狀態(tài)模式
狀態(tài)模式,當對象的內部狀態(tài)發(fā)生了改變的時候,允許對象執(zhí)行不同的流程。

優(yōu)點:
- 封裝了狀態(tài)轉換規(guī)則。
- 枚舉了可能的狀態(tài),在枚舉狀態(tài)之前需要確定狀態(tài)的種類。
- 將所有與某個狀態(tài)有關的行為放到一個類中,并且可以方便地增加新的狀態(tài),只需要改變對象狀態(tài)即可改變對象的行為。
- 允許狀態(tài)轉換邏輯與狀態(tài)對象合成一體,而不是某一個巨大的條件語句塊。
- 可以讓多個環(huán)境對象共享一個狀態(tài)對象,從而減少系統(tǒng)中對象的個數。
缺點:
- 狀態(tài)模式的使用必然會增加系統(tǒng)類和對象的個數。
- 狀態(tài)模式的結構與實現都較為復雜,如果使用不當將導致程序結構和代碼的混亂。
- 狀態(tài)模式對 “開閉原則” 并不太好,對于可以切換狀態(tài)的狀態(tài)模式,增加新的狀態(tài)類需要修改那些負責狀態(tài)轉換的源代碼,否則無法切換到新增狀態(tài),而且修改某個狀態(tài)類的行為也需修改對應類的源代碼。
應用場景
- 行為隨狀態(tài)改變而改變的場景。
- 條件、分支語句的代替者。
代碼示例

這是一個狀態(tài)圖,具有 “有 25 分錢”、“沒有 25 分錢”、“售出糖果”、“糖果售罄” 這 4 個狀態(tài)。同時也對應 4 個動作:“投入 25 分錢”,“退回 25 分錢”,“轉動曲柄” 和 “發(fā)放糖果”。
class State:
# 定義state基類
def insert_quarter(self):
pass
def eject_quarter(self):
pass
def turn_crank(self):
pass
def dispense(self):
pass
class SoldOutState(State):
# 繼承State 類
def __init__(self, gumball_machine):
self.gumball_machine = gumball_machine
def __str__(self):
return "sold_out"
def insert_quarter(self):
print("You can't insert a quarter, the machine is sold out")
def eject_quarter(self):
print("You can't eject, you haven't inserted a quarter yet")
def turn_crank(self):
print("You turned, but ther are no gumballs")
def dispense(self):
print("No gumball dispensed")
class SoldState(State):
# 繼承State 類
def __init__(self, gumball_machine):
self.gumball_machine = gumball_machine
def __str__(self):
return "sold"
def insert_quarter(self):
print("Please wait, we're already giving you a gumball")
def eject_quarter(self):
print("Sorry, you already turned the crank")
def turn_crank(self):
print("Turning twice doesn't get you another gumball")
def dispense(self):
self.gumball_machine.release_ball()
if gumball_machine.count > 0:
self.gumball_machine.state = self.gumball_machine.no_quarter_state
else:
print("Oops, out of gumballs!")
self.gumball_machine.state = self.gumball_machine.soldout_state
class NoQuarterState(State):
# 繼承State 類
def __init__(self, gumball_machine):
self.gumball_machine = gumball_machine
def __str__(self):
return "no_quarter"
def insert_quarter(self):
# 投幣 并且改變狀態(tài)
print("You inserted a quarter")
self.gumball_machine.state = self.gumball_machine.has_quarter_state
def eject_quarter(self):
print("You haven't insert a quarter")
def turn_crank(self):
print("You turned, but there's no quarter")
def dispense(self):
print("You need to pay first")
class HasQuarterState(State):
# 繼承State 類
def __init__(self, gumball_machine):
self.gumball_machine = gumball_machine
def __str__(self):
return "has_quarter"
def insert_quarter(self):
print("You can't insert another quarter")
def eject_quarter(self):
print("Quarter returned")
self.gumball_machine.state = self.gumball_machine.no_quarter_state
def turn_crank(self):
print("You turned...")
self.gumball_machine.state = self.gumball_machine.sold_state
def dispense(self):
print("No gumball dispensed")
class GumballMachine:
def __init__(self, count=0):
self.count = count
# 找出所有狀態(tài),并創(chuàng)建實例變量來持有當前狀態(tài),然后定義狀態(tài)的值
self.soldout_state = SoldOutState(self)
self.no_quarter_state = NoQuarterState(self)
self.has_quarter_state = HasQuarterState(self)
self.sold_state = SoldState(self)
if count > 0:
self.state = self.no_quarter_state
else:
self.state = self.soldout_state
def __str__(self):
return ">>> Gumball machine current state: %s" % self.state
def insert_quarter(self):
# 投入25分錢
self.state.insert_quarter()
def eject_quarter(self):
# 退回25分
self.state.eject_quarter()
# print("state", self.state, type(self.state))
def turn_crank(self):
# 轉動曲柄
# print("state", self.state, type(self.state))
self.state.turn_crank()
def release_ball(self):
# 發(fā)放糖果
print("A gumball comes rolling out the slot...")
if self.count > 0:
self.count -= 1
if __name__ == "__main__":
# 以下是代碼測試
gumball_machine = GumballMachine(5) # 裝入5 個糖果
print(gumball_machine)
gumball_machine.insert_quarter() # 投入25分錢
gumball_machine.turn_crank() # 轉動曲柄
print(gumball_machine)
gumball_machine.insert_quarter() #投入25分錢
gumball_machine.eject_quarter() # 退錢
gumball_machine.turn_crank() # 轉動曲柄
print(gumball_machine)
gumball_machine.insert_quarter() # 投入25分錢
gumball_machine.turn_crank() # 轉動曲柄
gumball_machine.insert_quarter() # 投入25分錢
gumball_machine.turn_crank() # 轉動曲柄
gumball_machine.eject_quarter() # 退錢
print(gumball_machine)
總結
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注腳本之家的更多內容!
相關文章
jupyter?notebook?自定義python解釋器的過程詳解
大家都知道jupyter?notebook?網頁版交互環(huán)境,類似于ipython,功能強大,這篇文章主要介紹了jupyter?notebook?自定義python解釋器的過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-10-10
Keras 數據增強ImageDataGenerator多輸入多輸出實例
這篇文章主要介紹了Keras 數據增強ImageDataGenerator多輸入多輸出實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-07-07
詳解Python list和numpy array的存儲和讀取方法
這篇文章主要介紹了詳解Python list和numpy array的存儲和讀取方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11

