posts - 241,  comments - 116,  trackbacks - 0
          實現(xiàn)狀態(tài)機有多種模式,其中最靈活而強大的方式是通過遷移表來實現(xiàn),該方式的缺點之一是需要編寫大量小塊代碼去支持遷移表。而在C#3.0中,可以以一種非常優(yōu)雅的方式實現(xiàn)。
          除了有限狀態(tài)機外,還有有限自動機,有限自動機一般用于分析字符,比如利用有限自動機分析正則表達式
          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("門是關(guān)上的,拉了也白拉");
                      //rule[State.Open][Operation.Push] = () => Console.WriteLine("門是開的,不用推了,直接進去吧");
                  }

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

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

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

              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("門是關(guān)上的,拉了也白拉");
                      //rule[State.Open][Operation.Push] = () => Console.WriteLine("門是開的,不用推了,直接進去吧");
                  }

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

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

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


          網(wǎng)站導(dǎo)航:
          博客園   IT新聞   Chat2DB   C++博客   博問  
           
          人人游戲網(wǎng) 軟件開發(fā)網(wǎng) 貨運專家
          主站蜘蛛池模板: 丰都县| 高平市| 建德市| 南郑县| 正定县| 镇远县| 油尖旺区| 综艺| 云阳县| 吉隆县| 邢台县| 突泉县| 宣城市| 长寿区| 大方县| 黄平县| 武隆县| 舒城县| 盐城市| 安平县| 佛坪县| 冷水江市| 井冈山市| 周口市| 政和县| 民和| 洛隆县| 建阳市| 千阳县| 城口县| 阜平县| 临沂市| 于田县| 岳西县| 嘉黎县| 通渭县| 哈巴河县| 车险| 固阳县| 依安县| 乐安县|