A Finite state machine under elegant implementation C # 3.0

A Finite state machine under elegant implementation C # 3.0

Implement a state machine has a variety of modes, the most flexible and powerful way is achieved through the migration table, one disadvantage of this approach is the need to write code to support the migration of a large number of small tables. In C # 3.0 can be implemented in a very elegant way.

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()
        {
            //
Normal operation             rule [ State .Closed] [ Operation .push] = () => { Console .WriteLine ( " door was pushed " ); State = State .Open;};             rule [ State .Open] [ Operation .Pull ] = () => { Console .WriteLine ( " door pulled on " ); State = State .Closed;}; //// added several special cases of treatment //rule[State.Closed][Operation. pull] = () => Console.WriteLine ( " the door is closed, the pull pulled and white "); //rule[State.Open][Operation.Push] = () => Console.WriteLine ( " door open, do not push, directly into it ");



            

            
            
        }

        Public void Process ( Operation OP)
        {
            the try
            {
                rule [State] [OP] ();
            }
            the catch ( a KeyNotFoundException )
            {

                Console .WriteLine ( String .Format ( "
door {0} does not allow a state where {1} Operation " , State, OP));
            }
            
        }
    }
}

Can be seen from the code, the lambda expression can be simplified transfer table structure, and more intuitive.

Configuration by means of a state transition table that is less than machine speed queries, each operation must be performed twice in order to query the status of the switching operation in the present embodiment. If the state is more time-consuming, and here I put it improved a bit, so that each operation requires only query once.


    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));
            }
        }
    }

转载于:https://www.cnblogs.com/zhangchenliang/archive/2012/09/01/2667172.html

Guess you like

Origin blog.csdn.net/weixin_34268843/article/details/93495248