posts - 241,  comments - 116,  trackbacks - 0
          實(shí)現(xiàn)狀態(tài)機(jī)有多種模式,其中最靈活而強(qiáng)大的方式是通過遷移表來實(shí)現(xiàn),該方式的缺點(diǎn)之一是需要編寫大量小塊代碼去支持遷移表。而在C#3.0中,可以以一種非常優(yōu)雅的方式實(shí)現(xiàn)。
          除了有限狀態(tài)機(jī)外,還有有限自動機(jī),有限自動機(jī)一般用于分析字符,比如利用有限自動機(jī)分析正則表達(dá)式
          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("門是開的,不用推了,直接進(jìn)去吧");
                  }

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

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

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

              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("門是開的,不用推了,直接進(jìn)去吧");
                  }

                  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 墻頭草 閱讀(1088) 評論(0)  編輯  收藏

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


          網(wǎng)站導(dǎo)航:
           
          人人游戲網(wǎng) 軟件開發(fā)網(wǎng) 貨運(yùn)專家
          主站蜘蛛池模板: 宁晋县| 屏东市| 龙江县| 沂源县| 策勒县| 隆回县| 扬中市| 汝州市| 西盟| 郧西县| 德格县| 贵德县| 合作市| 顺义区| 岱山县| 怀化市| 封丘县| 南郑县| 巍山| 蒙自县| 北流市| 当阳市| 孝昌县| 南漳县| 肇东市| 高清| 孟州市| 濉溪县| 乐都县| 福建省| 嘉祥县| 衡水市| 万载县| 石河子市| 正阳县| 柳州市| 乌鲁木齐县| 台江县| 阿合奇县| 本溪市| 顺平县|