posts - 241,  comments - 116,  trackbacks - 0
          實現狀態機有多種模式,其中最靈活而強大的方式是通過遷移表來實現,該方式的缺點之一是需要編寫大量小塊代碼去支持遷移表。而在C#3.0中,可以以一種非常優雅的方式實現。
          除了有限狀態機外,還有有限自動機,有限自動機一般用于分析字符,比如利用有限自動機分析正則表達式
          using System;
          using System.Collections.Generic;
          using System.Linq;
          using System.Text;

          namespace StateMachine
          {
              class Program
              {
                  static void Main(string[] args)
                  {
                      var door = new Door(State.Open);

                      while (true)
                      {
                          string s = Console.ReadLine();
                          Operation op = string.IsNullOrEmpty(s) ? Operation.Push : Operation.Pull;
                          door.Process(op);
                      }
                  }
              }

              enum Operation
              {
                  Push, Pull
              }

              enum State
              {
                  Open, Closed
              }

              class Door
              {
                  public State State { get; set; }

                  Dictionary<State, Dictionary<Operation, Action>> rule;
                  public Door(State state)
                  {
                      this.State = state;

                      rule = new Dictionary<State, Dictionary<Operation, Action>>();
                      foreach (var e in Enum.GetValues(typeof(State)))
                      {
                          rule[(State)e] = new Dictionary<Operation, Action>();
                      }

                      InitOperationRule();
                  }

                  void InitOperationRule()
                  {
                      //
          正常操作
                      rule[State.Closed][Operation.Push] = () => { Console.WriteLine("門被推開了"); State = State.Open; };
                      rule[State.Open][Operation.Pull] = () => { Console.WriteLine("
          門被拉上了"); State = State.Closed; };

                      ////
          加入幾種特殊情況的處理
                      //rule[State.Closed][Operation.Pull] = () => Console.WriteLine("門是關上的,拉了也白拉");
                      //rule[State.Open][Operation.Push] = () => Console.WriteLine("門是開的,不用推了,直接進去吧");
                  }

                  public void Process(Operation op)
                  {
                      try
                      {
                          rule[State][op]();
                      }
                      catch (KeyNotFoundException)
                      {

                          Console.WriteLine(string.Format("
          門在{0}狀態下不允許{1}操作", State, op));
                      }
                      
                  }
              }
          }

          從代碼中可以看到,通過lambda表達式,可以簡化遷移表的構造,并且更加直觀。
          通過遷移表構造狀態機的一種不足在于查詢速度,在本例中每個操作都要進行兩次查詢才能進行狀態轉換操作。如果狀態較多則非常費時,這里我把它改進了一下,使得每次操作只需要查詢一次即可。

              class DoorPlus
              {
                  State state;
                  public State State
                  {
                      get { return state; }
                      set
                      {
                          if (state != value)
                              currentOpRule = rule[value];
                          state = value;
                      }
                  }

                  Dictionary<Operation, Action> currentOpRule;
                  Dictionary<State, Dictionary<Operation, Action>> rule;
                  public DoorPlus(State state)
                  {
                      this.State = state;

                      rule = new Dictionary<State, Dictionary<Operation, Action>>();
                      foreach (var e in Enum.GetValues(typeof(State)))
                      {
                          rule[(State)e] = new Dictionary<Operation, Action>();
                      }

                      currentOpRule = rule[State];

                      InitOperationRule();
                  }

                  void InitOperationRule()
                  {
                      //
          正常操作
                      rule[State.Closed][Operation.Push] = () => { Console.WriteLine("門被推開了"); State = State.Open; };
                      rule[State.Open][Operation.Pull] = () => { Console.WriteLine("
          門被拉上了"); State = State.Closed; };

                      ////
          加入幾種特殊情況的處理
                      //rule[State.Closed][Operation.Pull] = () => Console.WriteLine("門是關上的,拉了也白拉");
                      //rule[State.Open][Operation.Push] = () => Console.WriteLine("門是開的,不用推了,直接進去吧");
                  }

                  public void Process(Operation op)
                  {
                      try
                      {
                          currentOpRule[op]();
                      }
                      catch (KeyNotFoundException)
                      {

                          Console.WriteLine(string.Format("
          門在{0}狀態下不允許{1}操作", State, op));
                      }
                  }
              }
          posted on 2008-11-25 11:55 墻頭草 閱讀(1088) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          人人游戲網 軟件開發網 貨運專家
          主站蜘蛛池模板: 孟连| 绥化市| 鄂托克旗| 肥乡县| 台安县| 公安县| 砀山县| 客服| 鹤壁市| 拉萨市| 招远市| 竹北市| 平度市| 田东县| 疏勒县| 读书| 南靖县| 原阳县| 绍兴市| 邹平县| 平江县| 东源县| 日照市| 辽源市| 台湾省| 博白县| 望奎县| 泾川县| 伊川县| 江山市| 南华县| 合山市| 苏尼特左旗| 溧水县| 昌黎县| 泉州市| 巴南区| 金门县| 宣恩县| 体育| 开化县|