設(shè)計模式之狀態(tài)模式_第1頁
已閱讀5頁,還剩18頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、設(shè)計模式之狀態(tài)模式定義 無數(shù)時候,一個對象的行為會按照一個動態(tài)的屬性變幻而變幻,這樣的一個對象我們可以稱為是有狀態(tài)的對象. 那么狀態(tài)模式就是允許一個對象在其內(nèi)部狀態(tài)轉(zhuǎn)變時候去轉(zhuǎn)變對象的行為. 狀態(tài)模式的關(guān)鍵就是區(qū)別其對象內(nèi)部動態(tài)變幻狀態(tài)是什么. 現(xiàn)實世界舉例論證 一個電燈泡,有一個開關(guān)按鈕, 默認是關(guān)閉狀態(tài),按一下切換到亮燈狀態(tài),再按一下切換到關(guān)閉狀態(tài),循環(huán)往復(fù). 我們用法面對對象寫法實現(xiàn)上述的場景. class button constructor (light) this.light = light; onpress () if (this.light.status = &39;close

2、&39;) this.light.status = &39;open&39; console.log(&39;開燈&39;); else this.light.status = &39;close&39; console.log(&39;關(guān)燈&39;); class light constructor () this.status = &39;close&39; const light = new light(); const button = new button(light); button.onpress(); button.onpress(); button.onpress(); 但是

3、現(xiàn)實場景中有些燈的狀態(tài)不只是開關(guān),比如它還是惟獨一個開關(guān),第一次按是開弱光,再按是開強光,再按才是關(guān),依次循環(huán). 此時我們的代碼如何根據(jù)下述辦法擴展: class button constructor (light) this.light = light; onpress () if (this.light.status = &39;close&39;) this.light.status = &39;light&39; console.log(&39;開弱光燈&39;); else if (this.light.status = &39;light&39;) this.light.statu

4、s = &39;strong&39; console.log(&39;開強光燈&39;); else this.light.status = &39;close&39; console.log(&39;關(guān)燈&39;); 你會發(fā)下上述代碼的缺點: 違背solid中的o原則(對擴綻開發(fā),對修改關(guān)閉)。 每次增強一個燈的狀態(tài),就要修該onpress辦法,使得代碼十分不穩(wěn)定,不利于維護. 過多的if else, 不利于代碼閱讀. 我們可以用法狀態(tài)模式對上述代碼舉行重構(gòu). 找出狀態(tài)對象中的可變屬性,將其抽象為一個單獨的類,跟這個狀態(tài)有關(guān)的行為都封裝在其類里面. class button construc

5、tor (light) this.weaklightstatus = new weaklightstatus(light); this.stronglightstatus = new stronglightstatus(light); this.offlightstatus = new offlightstatus(light); onpress () thislight.status.onpress(); class light constructor () this.status = &39;offlightstatus&39; / 切換狀態(tài)類 setstatus (statusclass

6、) this.status = statusclass; / 抽象類 class lightstatus constructor (light) this.light = light; / 弱光 class weaklightstatus extends lightstatus constructor (light) super(light); onpress () this.light.setstatus(&39;stronglightstatus&39;); console.log(&39;開弱光燈&39;); / 強光 class stronglightstatus extends li

7、ghtstatus constructor (light) super(light); onpress () this.light.setstatus(&39;offlightstatus&39;); console.log(&39;開強光燈&39;); / 關(guān)閉 class offlightstatus extends lightstatus constructor (light) super(light); onpress () this.light.setstatus(&39;weaklightstatus&39;); console.log(&39;關(guān)燈&39;); const lig

8、ht = new light(); const button = new button(light); button.onpress(); button.onpress(); button.onpress(); button.onpress(); 通過重構(gòu)之后的代碼, 很顯然就是提供了代碼的可閱讀性, 可維護性.便利后續(xù)需求的擴展,雖然會增強一定的代碼量. 現(xiàn)在我們通過對gof書中對狀態(tài)模式的定義來加深自己的總結(jié): 允許一個對象在其內(nèi)部狀態(tài)變幻時候去轉(zhuǎn)變它的行為, 對象似乎看起來轉(zhuǎn)變了它的類 歸納分析: 把變幻的屬性(狀態(tài))封裝成不同的類, 并把哀求托付給當(dāng)前的對象狀態(tài), 不同的狀態(tài)此時執(zhí)行不

9、同的行為 從用法者角度看, 我們用法的對象在不同狀態(tài)下有不同的行為, 彷佛這個對象是由不同類實例化而來, 這是由于哀求托付的緣故. 模式結(jié)構(gòu) 狀態(tài)模式包含如下角色: context: 環(huán)境類 state: 抽象狀態(tài)類 concretestate: 詳細狀態(tài)類 類比之前我們上述的實例場景: context指的就是button類. state指的就是lightstatus. concretestate指的就是各個不同狀態(tài)的類. 狀態(tài)模式描述了對象狀態(tài)的變幻以及對象如何在每一種狀態(tài)下表現(xiàn)出不同的行為。 狀態(tài)模式的關(guān)鍵是引入了一個抽象類來特地表示對象的狀態(tài),這個類我們叫做抽象狀態(tài)類,而對象的每一種詳細

10、狀態(tài)類都繼承了該類,并在不同詳細狀態(tài)類中實現(xiàn)了不同狀態(tài)的行為,包括各種狀態(tài)之間的轉(zhuǎn)換。 在狀態(tài)模式結(jié)構(gòu)中需要理解環(huán)境類與抽象狀態(tài)類的作用: 環(huán)境類事實上就是擁有狀態(tài)的對象,環(huán)境類有時候可以充當(dāng)狀態(tài)管理器(state manager)的角色,可以在環(huán)境類中對狀態(tài)舉行切換操作。 抽象狀態(tài)類可以是抽象類,也可以是接口,不同狀態(tài)類就是繼承這個父類的不同子類,狀態(tài)類的產(chǎn)生是因為環(huán)境類存在多個狀態(tài),同時還滿足兩個條件: 這些狀態(tài)常常需要切換,在不同的狀態(tài)下對象的行為不同。因此可以將不同對象下的行為單獨提取出來封裝在詳細的狀態(tài)類中,使得環(huán)境類對象在其內(nèi)部狀態(tài)轉(zhuǎn)變時可以轉(zhuǎn)變它的行為,對象看起來似乎修改了它的類

11、,而事實上是因為切換到不同的詳細狀態(tài)類實現(xiàn)的。因為環(huán)境類可以設(shè)置為任一詳細狀態(tài)類,因此它針對抽象狀態(tài)類舉行編程,在程序運行時可以將任一詳細狀態(tài)類的對象設(shè)置到環(huán)境類中,從而使得環(huán)境類可以轉(zhuǎn)變內(nèi)部狀態(tài),并且轉(zhuǎn)變行為。 狀態(tài)模式的優(yōu)缺點 優(yōu)點: 狀態(tài)模式定義的狀態(tài)-行為的對應(yīng)關(guān)系, 并將其封裝在一個類里面, 我們只需要擴展詳細狀態(tài)類就可以擴展需求. 避開了context類的代碼無限膨脹和過多的條件分支推斷. context類中的哀求于詳細狀態(tài)類的行為隔離互補影響. 缺點: 假如狀態(tài)類無數(shù), 需要不斷擴展代碼量. 狀態(tài)模式的結(jié)構(gòu)與實現(xiàn)都較為復(fù)雜,假如用法不當(dāng)將導(dǎo)致程序結(jié)構(gòu)和代碼的混亂。 狀態(tài)模式對開閉

12、原則的支持并不太好,對于可以切換狀態(tài)的狀態(tài)模式,增強新的狀態(tài)類需要修改那些負責(zé)狀態(tài)轉(zhuǎn)換的源代碼,否則無法切換到新增狀態(tài);而且修改某個狀態(tài)類的行為也需修改對應(yīng)類的源代碼。 狀態(tài)模式的性能優(yōu)化點 管理state對像的創(chuàng)建與銷毀: 有兩種方式實現(xiàn). 1. 僅僅當(dāng)satte對象需要的時候才去創(chuàng)建(節(jié)約內(nèi)存).這個適合與那些state對象比較浩大的情景. 2. 一開頭就創(chuàng)建全部的state對象,適用于state對象不多,以及狀態(tài)頻繁切換用法的情景. 我們上面的例子是一開頭就創(chuàng)建了全部的state對象, 而且是為每一個context類實例都創(chuàng)建了一組state對象,事實上我們這些state對象是可以在不同的context類之間

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論