码迷,mamicode.com
首页 > 其他好文 > 详细

Lambda表达式实现有限状态机

时间:2014-08-06 21:51:32      阅读:281      评论:0      收藏:0      [点我收藏+]

标签:style   color   os   io   for   ar   cti   代码   

实现状态机有多种模式,其中最灵活而强大的方式是通过迁移表来实现,该方式的缺点之一是需要编写大量小块代码去支持迁移表。而在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));
            }
        }
    }

Lambda表达式实现有限状态机,布布扣,bubuko.com

Lambda表达式实现有限状态机

标签:style   color   os   io   for   ar   cti   代码   

原文地址:http://www.cnblogs.com/gc2013/p/3895265.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!