2010-04-26 72 views
3

我想模擬一種有限狀態機(有限狀態機)。我有一系列狀態(比如,從StateA到StateZ)。這個序列被稱爲一個鏈,並在內部實現爲一個List。我將按照我希望它們運行的​​順序添加狀態。設計狀態鏈

我的目的是能夠在我的電腦中製作一系列動作(例如,鼠標點擊)。 (我知道這已經完成了數十億次)。

所以的狀態定義爲:

  1. boolean Precondition() < - 檢查是否爲這種情況下,有些情況是真實的。例如,如果我想單擊程序的「記錄」按鈕,在此方法中,我將檢查程序的進程是否正在運行。如果是,則轉到鏈表中的下一個狀態,否則,轉到定義爲失敗狀態的內容(通常是它們的第一個狀態)。
  2. IState GetNextState() < - 返回下一個要評估的狀態。如果Precondition()成功,它應該產生鏈中的下一個狀態,否則它應該產生失敗狀態。
  3. Run()只需檢查Precondition()並設置內部數據,以使GetNextState()按預期工作。

於是,一個很自然的做法,這將是這樣的:

Chain chain = new Chain(); 
//chain.AddState(new State(Precondition, FailState, NextState) <- Method structure 
chain.AddState(new State(new WinampIsOpenCondition(), null, new <problem here, I want to referr to a state that still wasn't defined!>); 

最大的問題是,我想打,在這一點仍然沒有被定義爲一個國家的參考。我可以通過使用字符串來回避狀態並使用內部散列表來避開這個問題,但是沒有更清晰的選擇嗎?

我只能在構造函數中傳遞前提條件和失敗狀態,讓執行前的鏈條在每個狀態下將正確的下一個狀態放在公共屬性中,但這看起來有些尷尬。

回答

2

你可以做以下之一:

  • 定義nextState爲您的站t E級內的可變場,及導線上之後使用突變的狀態;例如setNextStatesetNextState方法可以被實現爲只允許它被調用一次;隨後的調用將導致IllegalStateException被拋出。
  • 更改State接口以簡單返回是否滿足前提條件(即,返回boolean),並在滿足前提條件時使用外部「協調器」類沿列表進行轉換。換句話說,你知道,未來狀態是在索引i + 1所以有沒有真正的需要每個國家都有它的後繼的顯性知識。

鑑於你的狀態機的簡單起見,我贊成第二種方法。

1

這可以爲Decorator模式一個完美的候選人。下一步裝飾(包裝)當前步驟。你可以建立整個國家鏈。

1

我同意@Adamski的第二點。除非您打算將狀態作爲圖算法進行遍歷,而不是使用外部中介來管理遍歷,否則狀態不需要知道自己的位置。

如果你真的有興趣的國家居然能可表示爲一棵樹(即使它完全線性的目前)回答您的new <problem here, I want to referr to a state that still wasn't defined!>);

的方式問題,我會解決這個問題是每一個行動我記錄我會設置任何類型的容器,如數組來保存一系列操作。然後我會記錄當前的操作,但是延遲將它添加到容器中。當我記錄第二個動作時,我會將它添加到前一個動作中,並將前一個動作放到數組上,然後保持當前動作。

當您進入執行調用時,您將推動不在容器上的最終操作以及定義FSM結束的操作。

所以,你會是這樣的

public State PreviousAction { get; set; } 
public IList<State> States { get; private set } 
public void QueueAction(State CurrentAction) 
{  
    if(PreviousAction != null) 
    {   
     States.Add(new State(PreviousAction, CurrentAction)   
    } 

    PreviousAction = CurrentAction;  
} 

public void Execute() 
{  
    States.Add(new State(PreviousAction, State.Terminator)); 

    States[0].Execute();  
}