C#基礎State模式(行為型模式)

字號:

在軟件構建過程中,考試大提示:某些對象的狀態(tài)如果改變,其行為也會隨之而發(fā)生變化,比如文檔處于只讀狀態(tài),其支持的行為和讀寫狀態(tài)支持的行為就可能完全不同,如何在運行時根據(jù)對象的狀態(tài)來透明的更改對象行為?而不會為對象操作和狀態(tài)轉化之間引入緊耦合?
    意圖:
    允許一個對象在其內部狀態(tài)改變時改變它的行為。從而使對象看起來似乎修改了其行為
    public class Context
    {
    private State m_State;
    public Context(State state)
    {
    m_State = state;
    }
    public void ChangeState(State state)
    {
    m_State = state;
    }
    public void Handle()
    {
    m_State.Operate(this);
    }
    }
    public abstract class State
    {
    public abstract void Operate(Context ctx);
    }
    public class ConcreteStateA : State
    {
    public override void Operate(Context ctx)
    {
    Console.WriteLine("The State is processed By A");
    ctx.ChangeState(new ConcreteStateB());
    }
    }
    public class ConcreteStateB : State
    {
    public override void Operate(Context ctx)
    {
    Console.WriteLine("The State is processed By B");
    ctx.ChangeState(new ConcreteStateA());
    }
    }
    class Program
    {
    static void Main(string[] args)
    {
    State state = new ConcreteStateB();
    Context ctx = new Context(state);
    ctx.Handle();
    ctx.Handle();
    ctx.Handle();
    ctx.Handle();
    Console.Read();
    }
    }
    從上面的代碼來看,我們抽象了一個狀態(tài)機的基類State,他有個一個抽象方法Operate,通過這個方法的參數(shù)來間接的調用上下文的引用。我們在ConcreteStateA和ConcreteStateB中實現(xiàn)了Operate方法,并且在執(zhí)行一段代碼之后自動切換到下一個狀態(tài),我們這里只存在兩種狀態(tài),所以他是互相切換的,我們可以添加多種狀態(tài),讓狀態(tài)一步步的切換。注意,狀態(tài)的切換不由Context來控制。在Context類中,我們保存了State的私有變量用來存儲當前Context的狀態(tài)。ChangeState方法我們讓新的狀態(tài)替換原有的狀態(tài)引用,相當于切換了狀態(tài)。Handle方法處理了客戶端的請求,并且State對象將操作自己對應的方法。我們通過多態(tài)的概念來自動調用對應的Operate方法。在Operate方法中,我們也可以不用傳Context引用,但是我們在狀態(tài)切換的時候,很有可能要改變Context其他的屬性或行為,所以這個地方傳遞Context引用。Context的Handle方法我們只是在這里做個演示進行互相切換,我們完全可以擴充其他的方法,先切換一個狀態(tài),再來調用狀態(tài)的Operate方法。當然State也可以擴充其他的方法,表明Context其他內容的變化
    考試大提示要點:
    State模式將所有與一個特定狀態(tài)相關的行為都放入一個State的子類對象中,在對象狀態(tài)切換時,切換響應的對象;但同時維持State的接口,這樣實現(xiàn)了具體操作與狀態(tài)轉換之間的解藕。
    為不同的狀態(tài)引入不同的對象使得狀態(tài)轉換變得更加明確,而且可以保證不會出現(xiàn)狀態(tài)不一致的情況,因為轉換是原子性的--即要么徹底轉換過來,要么不轉換
    如果State對象沒有實例變量,那么各個上下文可以共享同一個State對象,從而節(jié)省對象開銷。
    這種模式避免了我們寫大量的if else或switch case語句,但是很有可能會導致某些系統(tǒng)有過多的具體狀態(tài)類,并且由此導致開發(fā)人員可能會對所有的狀態(tài)類有所遺漏。