天天看點

設計模式實戰-狀态模式(State Pattern)(上)1 前言2 定義3 架構4 意義5 優點6 缺點

1 前言

有時一個對象的行為取決于一或多個動态變化的屬性(狀态),這樣的對象稱為有狀态的(stateful)對象,其對象狀态是從事先定義好的一系列值中取出。當這樣的對象與外部事件産生互動時,内部狀态就會改變,對象行為也随之變化。

在UML中可以使用狀态圖來描述對象狀态的變化。在狀态模式中,建立表示各種狀态的對象和一個行為随着狀态對象改變而改變的 context 對象。

2 定義

該模式中,類的行為基于其狀态改變。即允許一個對象在其内部狀态改變時改變它的行為,對象看起來似乎修改了它的類。其别名為狀态對象(Objects for States),狀态模式是一種對象行為型模式。

3 架構

Context-環境類

擁有狀态的對象,環境類有時可以充當狀态管理器(State Manager),在環境類中對狀态進行切換操作。

State-抽象狀态類

可以是抽象類,也可是接口,不同狀态類就是繼承這個父類的不同子類,狀态類的産生是由于環境類存在多個狀态,同時還滿足:這些狀态經常需要切換,在不同狀态下對象行為不同。

ConcreteState-具體狀态類

4 意義

解決:對象的行為依賴于它的狀态(屬性),并且可以根據它的狀态改變而改變它的相關行為。

狀态模式的關鍵是引入了一個抽象類來專門表示對象的狀态 - 抽象狀态類。而對象的每種具體狀态類都繼承該類,并在不同具體狀态類中實作不同狀态的行為,包括各種狀态之間的轉換。

可以将不同對象下的行為單獨提取出來封裝在具體的狀态類,使得環境類對象在其内部狀态改變時可以改變它的行為,對象看起來似乎修改了它的類,而實際上是由于切換到不同的具體狀态類實作的。

由于環境類可以設定為任一具體狀态類,是以它針對抽象狀态類進行程式設計,在程式運作時可以将任一具體狀态類的對象設定到環境類中,進而使得環境類可以改變内部狀态,并且改變行為。

5 優點

  1. 封裝了轉換規則
  2. 枚舉可能的狀态,在枚舉狀态之前需要确定狀态種類
  3. 将所有與某個狀态有關的行為放到一個類中,并且可以友善地增加新的狀态,隻需要改變對象狀态即可改變對象的行為。
  1. 允許狀态轉換邏輯與狀态對象合成一體,而不是某一個巨大的條件語句塊。
  2. 可以讓多個環境對象共享一個狀态對象,進而減少系統中對象的個數。

6 缺點

  1. 必然增加系統類和對象的個數
  2. 結構與實作都較為複雜,如果使用不當将導緻程式結構和代碼的混亂
  3. 對"開閉原則"支援不太好,對可切換狀态的狀态模式,增加新的狀态類需要修改那些負責狀态轉換的源代碼,否則無法切換到新增狀态,而且修改某個狀态類的行為也需修改對應類的源代碼
  4. 在DDD中,為所有狀态建立單獨的類會使系統變得複雜。對于實體狀态類來說,有些行 為來自于自身,有些行為繼承自抽象基類,這一方面在子類和父類之間形成緊耦合,另一方面使代碼的可讀性變差。但是,使用枚舉則非常簡單,與通過狀态模式來建立标準類型相比,枚舉可能是更好的方法。這裡我們同時得到了兩種方法的好處:

獲得了一個非常簡單的标準類型

又能有效地表示目前的狀态

繼續閱讀