iT邦幫忙

2022 iThome 鐵人賽

DAY 26
0
自我挑戰組

設計模式探索系列 第 26

[Day 26] 狀態模式 (3)

  • 分享至 

  • xImage
  •  

狀態模式優點

套用了狀態模式的糖果機程式,功能跟一開始的寫法相同,卻大幅增加了可維護性,因為它移除了那些複雜的if-else判斷,也可以維持封裝的特性─ 讓既有的程式碼(例如:狀態)拒絕修改,而又歡迎擴展(加入新狀態);而經過state整理後,可讀性也增加許多。
在狀態模式的架構下,機器會在不同的狀態中切換,每次切換整個機器的運作就會套用到當下的類別,使用那類別的所有方法。

狀態模式定義

而終於揭曉狀態模式的定義:

狀態模式可讓物件在內部狀態改變時改變其行為,讓物件彷彿變成另一個類別

狀態模式的類別圖如下:
https://ithelp.ithome.com.tw/upload/images/20221011/20140096yubPWqS63R.png

其中的context就是擁有狀態的類別,例如本利中的糖果機;而handle就包含原本類別的所有方法,每個子狀態都必須實作,context會依照當下的state做出對應的handle方式。

策略模式與狀態模式

這時,回顧最一開始的策略模式,是否發現他們的結構有點像呢?都是將會變化的方法定義成一個類別介面,再分別去進行實作。
我們再來回顧這兩個模式的用途:

  • 策略模式可以被當作 "製作子類別" 的替代方案,避免使用繼承來定義類別行為無法改變,使用組合物件來改變行為;在使用策略模式狀態時,雖然也可以在執行期動態改變內容,但通常會有特定的物件行為,可以說類別內容的切換只是附加功能而不是目的
  • 狀態模式將與狀態有關的行為封裝起來,並將行為委託給目前的狀態;它可以避免在原類別(context)中的大量if-else判斷,使用此方法後只要改變狀態來決定對應的行為。
    策略模式用將可互換的行為封裝起來,使用委託決定要使用的行為;而狀態模式的context物件會隨著時間改變狀態,而註定會在不同的狀態中改變切換,兩者的工作目的不相同。

策略模式Q&A

  • 狀態間的切換都是由context或狀態類別本身決定呢?
    => 弱狀態轉換是固定的,就適合放在context中;但如果狀態會動態改變,就適合放在狀態類別本身進行判斷。
  • 不同的context實例可以共用狀態類別嗎?
    => 可以,但要注意的就是如果要共用的話,狀態類別不能保存對應的context,否則就必須為每個context建立實例。
  • 使用狀態會增加類別的數量,是否值得?
    => 這是彈性的代價,但很值得,除非這個程式不需要長久維護,因為這避免了複雜的if-else判斷式,可以簡潔地表達各個狀態的特性;且類別不宜太多的關鍵在於公開給客戶的那些類別與方法,這些額外的類別並不用日客戶端看到(使用private等等)。

上一篇
[Day 25] 狀態模式 (2)
下一篇
[Day 27] 樣板方法模式 (1)
系列文
設計模式探索30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言