2012-04-20 40 views
0

有人可以說一個在軟件中使用狀態機的好例子(編譯器和解析器除外)嗎?有很好的實例重要性和狀態機的使用應該簡化軟件:-)狀態機示例

我想編寫.NET應用程序。

謝謝。

+0

請參閱http://stackoverflow.com/questions/255797/uses-for-state-machines。雖然不確定,但並不完全重複 – CharlesB 2012-04-20 20:15:49

回答

1

您可以將每個用戶界面視爲一臺大型機器。來自UI的每個事件(例如按鈕點擊,菜單選擇等)驅動到另一個狀態的轉換,這可能意味着新的頁面。

0

另一種情況是訂購。新訂單(新狀態)可以取消或修改,但不予退款。但是,一旦你已經完成了它,它不能被取消,但它可能會被退還。

0

隨機數發生器可以以某種方式被認爲是一個狀態機。您有一組輸入,如左移,加常數,乘以常數等。狀態是實際的當前隨機值。由於這種隨機數的數量是有限的,因此可以認爲它是某種有限狀態機。

1

您的操作系統內核調度程序/調度程序是一個狀態機。線程具有狀態 - 正在運行,準備就緒,睡眠,eventWaiting,暫停,終止。事件是來自IO設備驅動程序的硬件中斷和來自運行線程的軟件中斷。

1

顯示典型導航路徑的網站設計(類似於@ duffymo的答案)。下面是一個不完整的例子(由 「UML和模式應用」 的啓發(Craig Larman與)):

enter image description here

0
0

OpenGL庫是一個狀態機。它保持一個根據對庫函數的調用而改變的狀態。你可以在這裏看到它:http://www.cs.tufts.edu/research/graphics/resources/OpenGL/OpenGL.htm

狀態機可以使用的另一個範圍是視頻遊戲。設想一個相對聰明的敵人。這個敵人將有幾種狀態:攻擊,隱藏,死亡,跑步等。這可以由國家和事件來控制。當我編寫一個視頻遊戲作爲我的學位項目時,我使用了兩個狀態機:一個用於遊戲流程(演示屏幕,遊戲,選項等),另一個用於遊戲本身(提問,擲骰子,移動玩家等)

0

這裏是基本的FSM的玩具控制檯應用示例。

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

// DESC: QAD-FSM (Quick And Dirty Finite State Machine) 
// 
// Notes: In its simplest form a state machine is 
//  • A set of states 
//  • A set of events 
//  • A set of transitions that define 
//   the next state given the current state and event. 
//  • A method of tracking current state 
// 
// Example: 
// 
//  I want to create a different kind of door lock that 
//   has the following states: 
//   
//    1. LBS - Locked_Both_Sides 
//    2. UBS - Unlocked_Both_Sides 
//    3. LFO - Locked_From_Outside 
// 
//   and has the following events: 
//   
//    1. OKT - Outside Key Turn 
//    2. IKT - Inside Key Turn 
//    
//  Transistions will be as follows: 
//  
//  CurrState Event NextState Desc 
//  ======================================================== 
//  LBS   OKT  UBS   When both sides locked, outside key turn unlocks both sides 
//  LBS   IKT  LFO   When both sides locked, inside key turn unlocks inside 
//  UBS   OKT  LFO   When both sides unlocked, outside key turn locks outside 
//  UBS   IKT  LBS   When both sides unlocked, inside key turn locks both sides 
//  LFO   OKT  UBS   When only outside locked, outside key turn unlocks outside 
//  LFO   IKT  LBS   When only outside locked, inside key turn locks both sides. 

namespace FSM 
{ 
    // The FSM states 
    enum State 
    { 
     LBS, 
     UBS, 
     LFO 
    } 

    // The FSM events 
    enum Event 
    { 
     IKT, 
     OKT 
    } 

    class Transition 
    { 
     public State currState { get; set; } 
     public Event evnt { get; set; } 
     public State nextState { get; set; } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var fsm = new FSM(); 

      System.Console.WriteLine("Current State: " + fsm.StateDesc[fsm.CurrentState]); 

      string input = ""; 
      while (input != "x") 
      { 
       System.Console.Write("Enter key turn [IKT, OKT] or x to exit: "); 
       input = System.Console.ReadLine(); 
       if (input == "x") break; 
       Event evnt; 
       if (!Enum.TryParse(input, out evnt)) 
       { 
        System.Console.WriteLine("Invalid input: " + input + ", enter one of [IKT,OKT,x]"); 
        continue; 
       } 
       fsm.ChangeState(evnt); 
       System.Console.WriteLine("New State: " + fsm.StateDesc[fsm.CurrentState]); 
      } 

      System.Console.WriteLine(""); 
      System.Console.WriteLine("History"); 
      System.Console.WriteLine("==============================================="); 
      System.Console.WriteLine("CurrState(Event) => NextState"); 
      System.Console.WriteLine("==============================================="); 
      fsm.hist 
       .Select(h => h.currState.ToString() + "(" + h.evnt.ToString() + ") => " + h.nextState.ToString()) 
       .ToList() 
       .ForEach(h => System.Console.WriteLine(h)); 
     } 
    } 

    class FSM 
    { 
     public Dictionary<State, String> StateDesc = new Dictionary<State, String>() 
               { 
                {State.LBS, "Both Sides Locked"}, 
                {State.LFO, "Locked From Outside"}, 
                {State.UBS, "Both Sides Unlocked"} 
               }; 

     public List<Transition> hist = new List<Transition>(); 

     // Create FSM transitions. 
     List<Transition> trans = new List<Transition> 
      { 
       new Transition() { currState = State.LBS, evnt = Event.OKT, nextState = State.UBS }, 
       new Transition() { currState = State.LBS, evnt = Event.IKT, nextState = State.LFO }, 
       new Transition() { currState = State.UBS, evnt = Event.OKT, nextState = State.LFO }, 
       new Transition() { currState = State.UBS, evnt = Event.IKT, nextState = State.LBS }, 
       new Transition() { currState = State.LFO, evnt = Event.OKT, nextState = State.UBS }, 
       new Transition() { currState = State.LFO, evnt = Event.IKT, nextState = State.LBS }, 
      }; 

     public State CurrentState { get { var lt = hist.FirstOrDefault(); return lt == null ? State.UBS : lt.nextState; } } 

     public State? ChangeState(Event evnt) 
     { 
      var t = trans.Find(r => r.currState == CurrentState && r.evnt == evnt); 
      if (t == null) return null; // If you don't create transitions that cover all combinations this could happen. 
      hist.Insert(0, t); 
      return t.nextState; 
     } 
    } 
}