自我聯想學設計模式(初級版)-2-狀態模式
狀態模式顧名思義就是一個物件有多個狀態,這裡以談戀愛為例。
首先我們搞清楚為什麼要使用狀態模式,其實很簡單,就是減輕心智負擔,因為一個物件它的狀態不同,對於同一種事情的反應也不同,如果你女朋友心情好,那麼你要求什麼她也會答應,如果她心情差,那麼你同樣的要求就會有各種各樣的迴應。
假設她平時有3個狀態,你都熟悉的不得了,但是如果她看了更多書,有了新的認識,突然發展處了另外2個狀態。
那麼你怎麼處理和她的關係呢?
如果她又發展出了另外5個呢?
想想都恐怖。
所以此時,如果你能把她之前的狀態的處理都分類打包好,分配給多個人,讓這些人一一面對她的各個狀態,是不是你自己就會輕鬆多呢?
這個例子雖然不合適,大概意思就是這樣。
那如果我們看過重構這方面的書的話,這個if else或者switch case就是一個非常明顯的訊號,需要我們重構。
因為過多的if else 會消耗我們的心智,讓我們陷入一種混亂的狀態。
這就好比原來是特朗普除了各個國家和美國的外交,但特朗普覺得太累了,於是他說,你A你去對付中國,B你去對付俄羅斯,C你去對付法國。特朗普自己可以去排程誰去應付誰,也可以提前就給這些人安排好任務,讓這些人自己去處理。
這裡的你和特朗普,本來都是有一大堆switch case和if else要處理的。
現在不同了,現在你和特朗普什麼都不需要做了,讓另外一個人去做,這個人就是狀態類。
狀態模式沒什麼太大的難度。
有幾個要點。
1.可以先建立好所需State物件並且始終不銷燬它們,也可以僅當需要它們時才建立
什麼時候先建立呢?當狀態改變很頻繁時,避免反覆建立和銷燬的開銷。
什麼時候需要時才建立呢?當要進入的狀態在執行時不可知,並且上下文不經常改變狀態時。
1.誰定義狀態轉換?
可以由Context(你或川普)來控制狀態的轉換,也可以由State子類指定它們的身後狀態。
什麼時候由Context控制呢?如果該轉換的準則是固定的,那麼它們可在Context中完全實現。
何時由State子類控制呢?當讓State子類自身指定它們的後繼狀態以及何時進行轉換,通常更靈活更合適。
這需要Context增加一個介面,讓State物件顯示設定Context當前狀態。
這樣做的一個缺點是,一個State子類至少擁有一個其他子類的訊息,這就在各子類之間產生了實現依賴。
通常的做法是定義一個狀態基類,或狀態介面,按照Context的不同需求,設定介面。
然後子類都實現這些介面,只是實現的函式裡各自的處理不同。
如果函式太多都沒什麼用途,可以採用。最簡單的Start和End兩個統一介面。
在Start函式中做出該狀態啟動時需要做的動作,
在End函式中做出該狀態關閉時需要做的動作。