0

有人可以说一个在软件(编译器和解析器除外)中使用状态机的好例子吗?有一些非常重要的例子,状态机的使用应该简化软件:-)

我想编写 .NET 应用程序。

谢谢。

4

9 回答 9

1

您可以将您看到的每个 UI 视为一个大型状态机。UI 中的每个事件(例如按钮单击、菜单选择等)都会驱动转换到另一个状态,这可能意味着一个新页面。

于 2012-04-20T20:07:50.170 回答
1

显示典型导航路径的网站设计(类似于@duffymo 的答案)。这是一个不完整的示例(灵感来自“应用 UML 和模式”(Craig Larman)):

在此处输入图像描述

于 2012-04-21T16:15:31.703 回答
1

您的操作系统内核调度程序/调度程序是一个状态机。线程具有状态 - 运行、就绪、睡眠、事件等待、暂停、终止。这些事件是来自 IO 设备驱动程序的硬件中断和来自运行线程的软件中断。

于 2012-04-20T20:17:41.900 回答
0

有关状态机的一些示例(以 Umple 表示),请参见:

运河锁软件: http ://cruise.eecs.uottawa.ca/umpleonline/?example=CanalLockStateMachine&diagramtype=state

电信呼叫处理: http ://cruise.eecs.uottawa.ca/umpleonline/?example=Phone&diagramtype=state

车库门软件: http ://cruise.eecs.uottawa.ca/umpleonline/?example=GarageDoor&diagramtype=state

在航空公司预订系统中预订: http ://cruise.eecs.uottawa.ca/umpleonline/?example=Booking&diagramtype=state

于 2014-01-14T21:29:18.493 回答
0

另一种情况是订购。新订单(处于新状态)可以取消或修改,但不能退款。但是,一旦您将其完成状态,就无法取消,但可能会退款。

于 2012-04-20T20:14:23.143 回答
0

opengl 库是一个状态机。它保持一个状态,该状态根据对库函数的调用而变化。你可以在这里看到它:http ://www.cs.tufts.edu/research/graphics/resources/OpenGL/OpenGL.htm

可以使用状态机的另一个范围是视频游戏。想象一个相对聪明的敌人。这个敌人将有几种状态:攻击、隐藏、死亡、奔跑等。这可以由状态和事件控制。当我写一个视频游戏作为我的学位项目时,我使用了两个状态机:一个用于游戏流程(演示屏幕、游戏、选项等),另一个用于游戏本身(提问、掷骰子、移动玩家等) )

于 2014-01-17T10:22:29.073 回答
0

随机数生成器也可以以某种方式被视为状态机。您有一组输入,例如左移、加常数、乘以常数等。状态是实际的当前随机值。由于此类随机数的计数是有限的,因此可以将其视为某种有限状态机。

于 2012-04-20T20:17:14.793 回答
0

您可以在 .net 中使用面向方面的编程作为实现示例查看我的通用状态机。

它可以用在需要一些工作流逻辑的软件中,比如审批工作流。

https://github.com/rcarubbi/carubbi.statemachine

只需像这样创建您的实体:

    [InitialState("State1")]
    public class Entity : IStatedEntity
    {

        [Transition(From = "State1", To = "State2")]
        [Transition(From = "State3", To = "State1")]
        public void Method1()
        {
            Trace.WriteLine("Method1");
        }

        [Transition(From = "State2", To = "State1")]
        public string Method2()
        {
            Trace.WriteLine("Method2");
            return string.Empty;
        }

        [Transition(From = "State2", To = "State3")]
        [Transition(From = "State3", To = "State4")]
        public int Method3(int p1, int p2)
        {
            Trace.WriteLine("Method3");
            return p1 + p2;
        }


        public StateMachine StateMachine { get; set; }
   }

并以这种方式使用它:

      [TestMethod]
        public void TestMethod1()
        {
            StateMachine.Configure();
            var ent = new Entity
            {
                StateMachine =
                {
                    IgnoreInvalidOperations = true
                }
            };

            ent.StateMachine.TransitionStarted += StateMachine_TransitionStarted;
            ent.StateMachine.TransitionEnded += StateMachine_TransitionEnded;

            Trace.WriteLine(ent.StateMachine.CurrentState);
            ent.Method1();
            Trace.WriteLine(ent.StateMachine.CurrentState);
            ent.Method2();
            Trace.WriteLine(ent.StateMachine.CurrentState);
            ent.Method1();
            Trace.WriteLine(ent.StateMachine.CurrentState);
            var result = ent.Method3(2, 4);
            Trace.WriteLine(ent.StateMachine.CurrentState);
            var result2 = ent.Method3(4, 4);
            Trace.WriteLine(ent.StateMachine.CurrentState);
            var result3 = ent.Method3(4, 4);
            Trace.WriteLine(ent.StateMachine.CurrentState);
        }

        private void StateMachine_TransitionEnded(object sender, TransitionEventArgs e)
        {

        }


        private void StateMachine_TransitionStarted(object sender, TransitionStartedEventArgs e)
        {

        }
   }
于 2018-10-11T15:40:31.563 回答
0

这是一个基本 FSM 的玩具控制台应用程序示例。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

//  DESC: QAD-FSM (Quick And Dirty Finite State Machine)
//  
//  Notes: In its simplest form a state machine is
//       • A set of states
//       • A set of events
//       • A set of transitions that define 
//           the next state given the current state and event.
//       • A method of tracking current state
// 
//  Example:
// 
//       I want to create a different kind of door lock that
//           has the following states:
//          
//               1. LBS - Locked_Both_Sides
//               2. UBS - Unlocked_Both_Sides
//               3. LFO - Locked_From_Outside
// 
//           and has the following events:
//          
//               1. OKT - Outside Key Turn
//               2. IKT - Inside Key Turn
//              
//       Transistions will be as follows:
//      
//       CurrState  Event   NextState   Desc
//       ========================================================
//       LBS            OKT     UBS         When both sides locked, outside key turn unlocks both sides
//       LBS            IKT     LFO         When both sides locked, inside key turn unlocks inside
//       UBS            OKT     LFO         When both sides unlocked, outside key turn locks outside
//       UBS            IKT     LBS         When both sides unlocked, inside key turn locks both sides
//       LFO            OKT     UBS         When only outside locked, outside key turn unlocks outside
//       LFO            IKT     LBS         When only outside locked, inside key turn locks both sides.

namespace FSM
{
    // The FSM states
    enum State
    {
        LBS,
        UBS,
        LFO
    }

    // The FSM events
    enum Event
    {
        IKT,
        OKT
    }

    class Transition
    {
        public State currState { get; set; }
        public Event evnt { get; set; }
        public State nextState { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var fsm = new FSM();

            System.Console.WriteLine("Current State: " + fsm.StateDesc[fsm.CurrentState]);

            string input = "";
            while (input != "x")
            {
                System.Console.Write("Enter key turn [IKT, OKT] or x to exit: ");
                input = System.Console.ReadLine();
                if (input == "x") break;
                Event evnt;
                if (!Enum.TryParse(input, out evnt))
                {
                    System.Console.WriteLine("Invalid input: " + input + ", enter one of [IKT,OKT,x]");
                    continue;
                }
                fsm.ChangeState(evnt);
                System.Console.WriteLine("New State: " + fsm.StateDesc[fsm.CurrentState]);
            }

            System.Console.WriteLine("");
            System.Console.WriteLine("History");
            System.Console.WriteLine("===============================================");
            System.Console.WriteLine("CurrState(Event) => NextState");
            System.Console.WriteLine("===============================================");
            fsm.hist
                .Select(h => h.currState.ToString() + "(" + h.evnt.ToString() + ") => " + h.nextState.ToString())
                .ToList()
                .ForEach(h => System.Console.WriteLine(h));
        }
    }

    class FSM
    {
        public Dictionary<State, String> StateDesc = new Dictionary<State, String>()
                                                { 
                                                    {State.LBS, "Both Sides Locked"},
                                                    {State.LFO, "Locked From Outside"},
                                                    {State.UBS, "Both Sides Unlocked"}
                                                };

        public List<Transition> hist = new List<Transition>();

        // Create FSM transitions.
        List<Transition> trans = new List<Transition>
            {
                new Transition() { currState = State.LBS, evnt = Event.OKT, nextState = State.UBS }, 
                new Transition() { currState = State.LBS, evnt = Event.IKT, nextState = State.LFO }, 
                new Transition() { currState = State.UBS, evnt = Event.OKT, nextState = State.LFO }, 
                new Transition() { currState = State.UBS, evnt = Event.IKT, nextState = State.LBS }, 
                new Transition() { currState = State.LFO, evnt = Event.OKT, nextState = State.UBS }, 
                new Transition() { currState = State.LFO, evnt = Event.IKT, nextState = State.LBS }, 
            };

        public State CurrentState { get { var lt = hist.FirstOrDefault(); return lt == null ? State.UBS : lt.nextState; } }

        public State? ChangeState(Event evnt)
        {
            var t = trans.Find(r => r.currState == CurrentState && r.evnt == evnt);
            if (t == null) return null; // If you don't create transitions that cover all combinations this could happen.
            hist.Insert(0, t);
            return t.nextState;
        }
    }
}
于 2015-09-29T22:05:03.590 回答