軟件設計模式:SDP04-08狀態(tài)模式_第1頁
軟件設計模式:SDP04-08狀態(tài)模式_第2頁
軟件設計模式:SDP04-08狀態(tài)模式_第3頁
軟件設計模式:SDP04-08狀態(tài)模式_第4頁
軟件設計模式:SDP04-08狀態(tài)模式_第5頁
已閱讀5頁,還剩28頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、狀態(tài)模式狀態(tài)模式n 模式動機與定義n 模式結構與分析n 模式實例與解析n 模式效果與應用n 模式擴展狀態(tài)模式模式動機n“人有悲歡離合,月有陰晴圓缺”,包括人在內,很多事物都具有多種狀態(tài),而且在不同狀態(tài)下會具有不同的行為,這些狀態(tài)在特定條件下還將發(fā)生相互轉換。就像水,它可以凝固成冰,也可以受熱蒸發(fā)后變成水蒸汽,水可以流動,冰可以雕刻,蒸汽可以擴散。n在UML中可以使用狀態(tài)圖來描述對象狀態(tài)的變化。 狀態(tài)模式模式動機中獎失戀開心do / 唱歌do / 請客吃飯.傷心do / 撞墻do / 瘋狂購物.狀態(tài)模式模式動機狀態(tài)模式模式動機n在軟件系統(tǒng)中,有些對象也像水一樣具有多種狀態(tài),這些狀態(tài)在某些情況下能

2、夠相互轉換,而且對象在不同的狀態(tài)下也將具有不同的行為。為了更好地對這些具有多種狀態(tài)的對象進行設計,我們將學習用于描述對象狀態(tài)及其轉換的狀態(tài)模式。狀態(tài)模式模式定義n狀態(tài)模式(State Pattern):允許一個對象在其內部狀態(tài)改變時改變它的行為,對象看起來似乎修改了它的類。其別名為狀態(tài)對象(Objects for States),狀態(tài)模式是一種對象行為型模式。n狀態(tài)模式用于解決系統(tǒng)中復雜對象的狀態(tài)轉換以及不同狀態(tài)下行為的封裝問題。狀態(tài)模式將一個對象的狀態(tài)從狀態(tài)模式將一個對象的狀態(tài)從該對象中分離出來,封裝到專門的狀態(tài)類中該對象中分離出來,封裝到專門的狀態(tài)類中,使得對象使得對象狀態(tài)可以靈活變化狀態(tài)

3、可以靈活變化,對于客戶端而言,無須關心對象狀態(tài)的轉換以及對象所處的當前狀態(tài),無論對于何種狀態(tài)的對象,客戶端都可以一致處理。狀態(tài)模式模式結構stateContext- state : State+request ()setState (State state).State+ handle ().ConcreteStateA+ handle ().ConcreteStateB+ handle ().state.handle();.狀態(tài)模式狀態(tài)模式包含如下角色nContext:環(huán)境類,又稱為上下文類,它是擁有多種狀態(tài)的對象。由于環(huán)境類的狀態(tài)存在多樣性且在不同狀態(tài)下對象的行為有所不同,因此將狀態(tài)獨立出

4、去形成單獨的狀態(tài)類。在環(huán)境類中維護一個抽象狀態(tài)類State的實例,這個實例定義當前狀態(tài),在具體實現(xiàn)時,它是一個State子類的對象。狀態(tài)模式狀態(tài)模式包含如下角色nState:抽象狀態(tài)類,它用于定義一個接口以封裝與環(huán)境類的一個特定狀態(tài)相關的行為,在抽象狀態(tài)類中聲明了各種不同狀態(tài)對應的方法,而在其子類中實現(xiàn)類這些方法,由于不同狀態(tài)下對象的行為可能不同,因此在不同子類中方法的實現(xiàn)可能存在不同,相同的方法可以寫在抽象狀態(tài)類中。nConcreteState:具體狀態(tài)類,它是抽象狀態(tài)類的子類,每一個子類實現(xiàn)一個與環(huán)境類的一個狀態(tài)相關的行為,每一個具體狀態(tài)類對應環(huán)境的一個具體狀態(tài),不同的具體狀態(tài)類其行為有所

5、不同。模式分析n狀態(tài)模式的關鍵是引入了一個抽象類來專門表示對象的狀態(tài),而對象的每一種具體狀態(tài)類都繼承了該類,并在不同具體狀態(tài)類中實現(xiàn)了不同狀態(tài)的行為,包括各種狀態(tài)之間的轉換。n典型的抽象狀態(tài)類代碼如下所示:狀態(tài)模式abstract class State /聲明抽象業(yè)務方法,不同的具體狀態(tài)類可以不同的實現(xiàn) public abstract void handle(); 模式分析n具體狀態(tài)類中實現(xiàn)了在抽象狀態(tài)類中聲明的業(yè)務方法,在實際使用時,可能包含多個業(yè)務方法,如果某些業(yè)務方法的實現(xiàn)完全相同,可以將這些方法移至抽象狀態(tài)類,實現(xiàn)代碼的復用。典型的具體狀態(tài)類代碼如下:class ConcreteSt

6、ate extends State public void handle() /方法具體實現(xiàn)代碼 狀態(tài)模式模式分析n環(huán)境類維持一個對抽象狀態(tài)類的引用,典型代碼如下所示:class Context private State state; /維持一個對抽象狀態(tài)對象的引用 private int value; /其他屬性值,該屬性值的變化可能會導致對象狀態(tài)發(fā)生變化 public void setState(State state) /注入不同的具體狀態(tài)對象 this.state = state; public void request() /其他代碼 state.handle(); /調用狀態(tài)對象

7、的業(yè)務方法 /其他代碼 狀態(tài)模式模式分析n環(huán)境類實際上是真正擁有狀態(tài)的對象,我們只是將環(huán)境類中與狀態(tài)有關的代碼提取出來封裝到專門的狀態(tài)類中。在狀態(tài)模式結構圖中,環(huán)境類Context與抽象狀態(tài)類State之間存在單向關聯(lián)關系,在Context中定義了一個State對象。在實際使用時,它們之間可能存在更為復雜的關系,State與Context之間可能也存在依賴或者關聯(lián)關系。n在狀態(tài)模式的使用過程中,一個對象的狀態(tài)之間還可以進行相互轉換,通常有兩種實現(xiàn)狀態(tài)轉換的方式:狀態(tài)模式模式分析n(1) 統(tǒng)一由環(huán)境類來負責狀態(tài)之間的轉換,此時,它充當了狀態(tài)管理器(State Manager)角色,在它的業(yè)務方法

8、中通過對某些屬性值的判斷實現(xiàn)狀態(tài)轉換,還可以提供一個專門的方法用于實現(xiàn)屬性判斷和狀態(tài)轉換,如下代碼段所示:public void changeState() if (value = 0) /判斷屬性值,根據(jù)屬性值進行狀態(tài)轉換 this.setState(new ConcreteStateA(); else if (value = 1) this.setState(new ConcreteStateB(); 狀態(tài)模式模式分析n(2) 由具體狀態(tài)類來負責狀態(tài)之間的轉換,可以在其業(yè)務在其業(yè)務方法中判斷環(huán)境類的某些屬性值方法中判斷環(huán)境類的某些屬性值為它設置新的狀態(tài)對象,實現(xiàn)狀態(tài)轉換,也可以提供一個專門

9、的方法來負責屬性判斷和狀態(tài)轉換。此時,兩者之間就存在依賴或關聯(lián)關系兩者之間就存在依賴或關聯(lián)關系:public void changeState(Context ctx) if (ctx.getValue() = 1) /根據(jù)環(huán)境對象中的屬性值進行狀態(tài)轉換 ctx.setState(new ConcreteStateB(); else if (ctx.getValue() = 2) ctx.setState(new ConcreteStateC(); 狀態(tài)模式模式分析n狀態(tài)類的產生是由于環(huán)境類存在多個狀態(tài),同時還滿足兩個條件:這些狀態(tài)經常需要切換,在不同的狀態(tài)下對象的行為不同。因此可以將不同對象

10、下的行為單獨提取出來封裝在具體的狀態(tài)類中,使得環(huán)境類對象在其內部狀態(tài)改變時可以改變它的行為,對象看起來似乎修改了它的類,而實際上是由于切換到不同的具體狀態(tài)類實現(xiàn)的。由于環(huán)境類可以設置為任一具體狀態(tài)類,因此它針對抽象狀態(tài)類進行編程,在程序運行時可以將任一具體狀態(tài)類的對象設置到環(huán)境類中,從而使得環(huán)境類可以改變內部狀態(tài),并且改變行為。狀態(tài)模式狀態(tài)模式狀態(tài)模式實例與解析n實例一:論壇用戶等級。在某論壇系統(tǒng)中,用戶可以發(fā)表留言,發(fā)表留言將增加積分;用戶也可以回復留言,回復留言也將增加積分;用戶還可以下載文件,下載文件將扣除積分。該系統(tǒng)用戶分為三個等級,分別是新手、高手和專家,這三個等級對應三種不同的狀態(tài)

11、,這三種狀態(tài)分別定義如下:(1) 如果積分小于100分,則為新手狀態(tài),用戶可以發(fā)表留言、回復留言,但是不能下載文件。 (2) 如果積分大于等于100分但小于1000分,則為高手狀態(tài),用戶可以發(fā)表留言、回復留言,還可以下載文件,而且用戶在發(fā)表留言時可以獲取雙倍積分。如果下載文件后積分小于0,則不能下載該文件。(3) 如果積分大于等于1000分,則為專家狀態(tài),用戶可以發(fā)表留言、回復留言和下載文件,用戶除了在發(fā)表留言時可以獲取雙倍積分外,下載文件只扣除所需積分的一半。如果下載文件后積分小于0,則不能下載該文件。狀態(tài)模式狀態(tài)模式實例與解析n實例一:論壇用戶等級 狀態(tài)模式狀態(tài)模式實例與解析n實例一:論壇

12、用戶等級參考代碼 (sample01)演示演示狀態(tài)模式狀態(tài)模式實例與解析n實例二:銀行賬戶,在某銀行系統(tǒng)定義的賬戶有三種狀態(tài):(1) 如果賬戶中余額大于等于0,此時賬戶的狀態(tài)為正常狀態(tài),既可以向賬戶存款也可以從中取款;(2) 如果賬戶中余額小于0,并且大于-2000,則賬戶的狀態(tài)為透支狀態(tài)(Overdraft State),此時用戶既可以向該賬戶存款也可以從該賬戶取款,但需要按天計算利息;(3) 如果賬戶中余額等于-2000,那么賬戶的狀態(tài)為受限狀態(tài)(Restricted State),此時用戶只能向該賬戶存款,不能再從中取款,同時也將按天計算利息;(4) 根據(jù)余額的不同,以上三種狀態(tài)可發(fā)生相

13、互轉換。狀態(tài)模式狀態(tài)模式實例與解析n實例二:銀行賬戶 狀態(tài)模式狀態(tài)模式實例與解析n實例二:銀行賬戶 狀態(tài)模式模式優(yōu)點n封裝了狀態(tài)的轉換規(guī)則,在狀態(tài)模式中可以將狀態(tài)的轉換代碼封裝在環(huán)境類或者具體狀態(tài)類中,可以對狀態(tài)轉換代碼進行集中管理,而不是分散在一個個業(yè)務方法中。n將所有與某個狀態(tài)有關的行為放到一個類中,只需要注入一個不同的狀態(tài)對象即可使環(huán)境對象擁有不同的行為。n允許狀態(tài)轉換邏輯與狀態(tài)對象合成一體,而不是提供一個巨大的條件語句塊,狀態(tài)模式可以讓我們避免使用龐大的條件語句來將業(yè)務方法和狀態(tài)轉換代碼交織在一起。n可以讓多個環(huán)境對象共享一個狀態(tài)對象,從而減少系統(tǒng)中對象的個數(shù)。狀態(tài)模式模式缺點n狀態(tài)模

14、式的使用必然會增加系統(tǒng)中類和對象的個數(shù),導致系統(tǒng)運行開銷增大。n狀態(tài)模式的結構與實現(xiàn)都較為復雜,如果使用不當將導致程序結構和代碼的混亂,增加系統(tǒng)設計的難度。n狀態(tài)模式對“開閉原則”的支持并不太好,增加新的狀態(tài)類需要修改那些負責狀態(tài)轉換的源代碼,否則無法轉換到新增狀態(tài);而且修改某個狀態(tài)類的行為也需修改對應類的源代碼。狀態(tài)模式模式適用環(huán)境n對象的行為依賴于它的狀態(tài)(如某些屬性值),狀態(tài)的改變將導致行為的變化。n在代碼中包含大量與對象狀態(tài)有關的條件語句,這些條件語句的出現(xiàn),會導致代碼的可維護性和靈活性變差,不能方便地增加和刪除狀態(tài),并且導致客戶類與類庫之間的耦合增強。模式應用n(1) 狀態(tài)模式在工作

15、流軟件中得以廣泛使用,甚至可以用于這些系統(tǒng)的核心功能設計,如在政府OA辦公系統(tǒng)中,一個批文的狀態(tài)有多種:尚未辦理;正在辦理;正在批示;正在審核;已經完成等各種狀態(tài),而且批文狀態(tài)不同時對批文的操作也有所差異。使用狀態(tài)模式可以描述工作流對象(如批文)的狀態(tài)轉換以及不同狀態(tài)下它所具有的行為。 狀態(tài)模式模式應用n(2) 在目前主流的RPG(Role Play Game,角色扮演游戲)中,使用狀態(tài)模式可以對游戲角色進行控制,游戲角色的升級伴隨著其狀態(tài)的變化和行為的變化。對于游戲程序本身也可以通過狀態(tài)模式進行總控,一個游戲活動包括開始、運行、結束等狀態(tài),通過對狀態(tài)的控制可以控制系統(tǒng)的行為,決定游戲的各個方

16、面,因此可以使用狀態(tài)模式對整個游戲的架構進行設計與實現(xiàn)。狀態(tài)模式狀態(tài)模式模式擴展n共享狀態(tài)在有些情況下多個環(huán)境對象需要共享同一個狀態(tài),如果希望在系統(tǒng)中實現(xiàn)多個環(huán)境對象實例共享一個或多個狀態(tài)對象,那么需要將這些狀態(tài)對象定義為環(huán)境的靜態(tài)成員對象。參考代碼 (ShareState)演示演示狀態(tài)模式模式擴展n簡單狀態(tài)模式:簡單狀態(tài)模式是指狀態(tài)都相互獨立,狀態(tài)之間無須進行轉換的狀態(tài)模式,這是最簡單的一種狀態(tài)模式。對于這種狀態(tài)模式,每個狀態(tài)類都封裝與狀態(tài)相關的操作,而無須關心狀態(tài)的切換,可以在客戶端直接實例化狀態(tài)類,然后將狀態(tài)對象設置到環(huán)境類中。如果是這種簡單的狀態(tài)模式,它遵循“開閉原則”,在客戶端可以針

17、對抽象狀態(tài)類進行編程,而將具體狀態(tài)類寫到配置文件中,同時增加新的狀態(tài)類對原有系統(tǒng)也不造成任何影響。狀態(tài)模式模式擴展n可切換狀態(tài)的狀態(tài)模式:大多數(shù)的狀態(tài)模式都是可以切換狀態(tài)的狀態(tài)模式,在實現(xiàn)狀態(tài)切換時,在具體狀態(tài)類內部需要調用環(huán)境類Context的setState()方法進行狀態(tài)的轉換操作,在具體狀態(tài)類中可以調用到環(huán)境類的方法,因此狀態(tài)類與環(huán)境類之間通常還存在關聯(lián)關系或者依賴關系。通過在狀態(tài)類中引用環(huán)境類的對象來回調環(huán)境類的setState()方法實現(xiàn)狀態(tài)的切換。在這種可以切換狀態(tài)的狀態(tài)模式中,增加新的狀態(tài)類可能需要修改其他某些狀態(tài)類甚至環(huán)境類源代碼,否則系統(tǒng)無法切換到新增狀態(tài)。 狀態(tài)模式模式擴

18、展n狀態(tài)模式和觀察者模式的區(qū)別n這兩個模式都是在狀態(tài)發(fā)生改變的時候觸發(fā)行為,只不過觀察者模式的行為是固定的,那就是通知所有的觀察者,而狀態(tài)模式是根據(jù)狀態(tài)來選擇不同的處理,當狀態(tài)發(fā)生改變的時候,動態(tài)改變行為。小結狀態(tài)模式允許一個對象在其內部狀態(tài)改變時改變它的行為,對象看起來似乎修改了它的類。其別名為狀態(tài)對象,狀態(tài)模式是一種對象行為型模式。狀態(tài)模式包含三個角色:環(huán)境類又稱為上下文類,它是擁有狀態(tài)的對象,在環(huán)境類中維護一個抽象狀態(tài)類State的實例,這個實例定義當前狀態(tài),在具體實現(xiàn)時,它是一個State子類的對象,可以定義初始狀態(tài);抽象狀態(tài)類用于定義一個接口以封裝與環(huán)境類的一個特定狀態(tài)相關的行為;具體狀態(tài)類是抽象狀態(tài)類的子類,每一個子類實現(xiàn)一個與環(huán)境類的一個狀態(tài)相關的行為,每一個具體狀態(tài)類對應環(huán)境的一個具體狀態(tài),不同的具體狀態(tài)類其行為有所不同。狀態(tài)模式描述了對象狀態(tài)的變化以及對象如何在每一種狀態(tài)下表現(xiàn)出不同的行為。小結狀態(tài)模式的主要優(yōu)點在于封裝了轉換規(guī)則,并枚舉可能的狀態(tài),它將所有與某

溫馨提示

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

評論

0/150

提交評論