本文為敏捷軟件開(kāi)發(fā) - 原則、模式與實(shí)踐系列的一部分。
本文對(duì)應(yīng)原書(shū)第29章
STATE模式
STATE模式既具有switch/case語(yǔ)句的效率又具有解釋遷移表的靈活性。

上圖展示該模式的結(jié)構(gòu)。Turnstile類(lèi)擁有關(guān)于事件的公有方法以及關(guān)于動(dòng)作的受保護(hù)方法。它持有一個(gè)指向TurnstileState接口的引用。當(dāng)Turnstile的兩個(gè)事件方法中的一個(gè)被調(diào)用時(shí),它就把這個(gè)事件委托給Turnstilestate對(duì)象。Turnstilestate的方法實(shí)現(xiàn)了LOCKED狀態(tài)下的相應(yīng)動(dòng)作。
TurnstileUnlockedState的方法實(shí)現(xiàn)了UNLOCKED狀態(tài)下的相應(yīng)動(dòng)作。為了改變FSM的狀態(tài),就要把這兩個(gè)派生類(lèi)之一的實(shí)例賦值給Turnstile對(duì)象中的引用。
STATE模式和STRATEGY模式
STATE模式和STRATEGY模式類(lèi)似,它們都有一個(gè)上下文類(lèi),都委托給一個(gè)具有幾個(gè)派生類(lèi)的多態(tài)基類(lèi)。不同之處(見(jiàn)下圖)在于,在STATE模式中,派生類(lèi)持有回指向上下文的引用。派生類(lèi)的主要功能是使用這個(gè)引用選擇并調(diào)用上下文類(lèi)中的方法。在STRATEGY模式中,不存在這樣的限制以及意圖。STRATEGY的派生類(lèi)不必持有指向上下文類(lèi)的引用,并且也不需要去調(diào)用上下文類(lèi)的方法。所以,所有的STATE模式實(shí)例同樣也是STRATEGY模式實(shí)例,但是并非所有的STRATEGY模式實(shí)例都是STATE模式實(shí)例。

STATE模式的代價(jià)和收益
STATE模式徹底地分離了狀態(tài)機(jī)的邏輯和動(dòng)作。動(dòng)作是在Context類(lèi)中實(shí)現(xiàn)的,而邏輯則是分布在State類(lèi)的派生類(lèi)中。這就使得二者可以非常容易地獨(dú)立變化、互不影響。例如,只要使用State類(lèi)的另一個(gè)派生類(lèi),就可以非常容易地在一個(gè)不同的狀態(tài)邏輯中重用Context類(lèi)的動(dòng)作。此外,我們也可以在不影響State派生類(lèi)邏輯的情況下創(chuàng)建Context子類(lèi)來(lái)更改或者替換動(dòng)作實(shí)現(xiàn)。
該方法的另外一個(gè)好處就是它非常高效。它基本上和嵌套switch/case實(shí)現(xiàn)的效率完全一樣。因此,該方法既具有表驅(qū)動(dòng)方法的靈活性,又具有嵌套swtich/case方法的效率。
這項(xiàng)技術(shù)的代價(jià)體現(xiàn)在兩個(gè)方面。第一,State派生類(lèi)的編寫(xiě)完全是一項(xiàng)乏味的工作。編寫(xiě)一個(gè)具有20個(gè)狀態(tài)的狀態(tài)機(jī)會(huì)使人精神麻木。第二,邏輯分散。無(wú)法在一個(gè)地方就看到整個(gè)狀態(tài)機(jī)邏輯。因此,這使得代碼難以維護(hù)。這會(huì)使人想起嵌套switch/case方法的晦澀性。
完整內(nèi)容請(qǐng)查看敏捷軟件開(kāi)發(fā) - 原則、模式與實(shí)踐系列