行爲型模式:State 狀態模式

                                                         行爲型模式:State 狀態模式

1、對象狀態影響對象行爲
  對象擁有不一樣的狀態,每每會行使不一樣的行爲...
 
2、動機(Motivation)
  1)在軟件構建過程當中,某些對象的狀態若是改變,其行爲也會隨之而發生變化,好比文檔處於只讀狀態,其支持的行爲和讀寫狀態支持的行爲就可能徹底不一樣。
  2)如何在運行時根據對象的狀態來透明地更改對象的行爲?而不會爲對象操做和狀態轉化之間引入緊耦合?
 
3、意圖(Intent)
  容許一個對象在其內部狀態改變時改變它的行爲。從而使對象看起來彷佛修改了其行爲。
                                                                                                          ——《設計模式》GoF
 
4、實例:文檔的處理(讀/寫)
  1)最初的設計
//文檔的幾種狀態用枚舉列舉出來,若是枚舉穩定,這樣設計很好
public enum DocumentState
{
  ReadOnly,
  Edittable,
}設計模式

public class Document
{
  DocumentState state;
 
  public Document(DocumentState state)
  {
    this.state = state;
  }
 
  //若是修改DocumentState,好比加一種狀態,這裏也要修改Handle方法
  public void Handle()
  {
    //使用is-else切換狀態,若是這種切換頻繁,而且有新的狀態加入,這時應考慮State模式了
    if (state == DocumentState.ReadOnly)
    {
    }
    else if (state == DocumentState.Edittable)
    {
    }
  }
} ide

  2)演化到State模式:
 與策略模式類似,但又不一樣,狀態模式最主要是可以在各狀態之間自由切換
//抽象類:表達狀態及依賴狀態的行爲
public abstract class StatedDocument
{
  //屬性:指定下一個狀態
  public abstract StatedDocument Next
  {
    get;
    set;
  }
 
  public abstract void Handle1();
  public abstract void Handle2();
  public abstract void Handle3();
}this

//只讀狀態
public class ReadOnlyState : StatedDocument
{
  private StatedDocument next = new ReadWriteState();
 
  //切換到下個狀態,這裏寫死了,切換到讀寫狀態,固然能夠根據須要設計出切換到任何狀態的代碼
  public override StatedDocument Next
  {
    get
    {
      return this.next;
    }
    set
    {
      this.next = value;
    }
  }
 
  public override void Handle1(){}
  public override void Handle2(){}
  public override void Handle3(){}
}設計

//讀寫狀態
public class ReadWriteState : StatedDocument
{
  private StatedDocument next = new ReadOnlyState();
 
  //切換到下個狀態,這裏寫死了,切換到只讀狀態
  public override StatedDocument Next
  {
    get
    {
      return this.next;
    }
    set
    {
      this.next = value;
    }
  }
 
  public override void Handle1(){}
  public override void Handle2(){}
  public override void Handle3(){}
}對象

//主邏輯:依賴的是一個抽象類StatedDocument
public class Document
{
  StatedDocument statedDocument;
 
  public void SetStatedDocument(StatedDocument statedDocument)
  {
    this.statedDocument = statedDocument
  }
 
  public void Handle1()
  {
    statedDocument.Handle1();
    //根據須要是切換仍是不切換狀態
    statedDocument = statedDocument.Next;
  }
 
  public void Handle2()
  {
    statedDocument.Handle2();
  }
 
  public void Handle3()
  {
    statedDocument.Handle3();
  }
}接口

5、State模式的幾個要點
  1)State模式將全部與一個特定狀態相關的行爲都放入一個State的子類對象中,在對象狀態切換時,切換相應的對象;但同時維持State的接口,這樣實現了具體操做與狀態轉換之間的解耦。
  2)爲不一樣的狀態引入不一樣的對象使得狀態轉換變得更加明確,並且能夠保證不會出現狀態不一致的狀況,由於轉換是原子性的——即要麼完全轉換過來,要麼不轉換。
  3)若是State對象沒有實例變量,那麼各個上下文能夠共享同一個State對象,從而節省對象開銷。文檔

相關文章
相關標籤/搜索