首页 > 其他分享 >实现一个所谓的状态机

实现一个所谓的状态机

时间:2024-01-21 22:35:30浏览次数:27  
标签:Envierment 实现 cmd else 状态机 所谓 Command btn public

问题的描述

最近在改仿真软件的状态切换 ,什么意思呢,这东西有点像个播放器,但是不仅仅是播放暂停那么简单。首先我们画一个图 ,以一个图说明:

 

 

通过以前的面向对象设计经验我们知道有一种叫状态机的东西, 简而言之就是把每个状态 通过节点对象包装 ,节点是什么类型就是当前处于什么状态,看到箭头的方向没 代表到另一个状态去 ,到的这个过程 我们 把抽象成状态对象的方法。基本思路是把节点抽象成泛化对象,能不能到哪个 到的过程中出现了异常又怎么办 ,分而治之的思想充分的体现了面向对象的威力。 原项目根本没有考虑到任何类似状态机这种的东西 ,全是用的判断,与业务嵌入太重。实际的比理想化的难得的多,但是我们不怕 不管怎样我们先开个头。

实现

首先不管如何所有的指令我们要罗列出来(启动,运行,暂停也叫冻结,停止,快照):

1 public enum Command
2 {
3     Start,
4     ToRun,
5     ToPause,
6     ToStop,
7     Snap
8 }

 

然后是对节点状态进行泛化,说白了就是抽象出几个状态了类,然后他们有一个共同基类,按钮是否变灰就是根据状态,来的。某个指令能不能执行显然这个是所有泛化对象都要有的,所以我们作为基类方法。

 1 public class BaseState
 2 {
 3     public string StateInfo { get; set; } = "未知状态";
 4     public string ErrorInfo { get; set; }
 5     public void Error()
 6     {
 7 
 8     }
 9 
10     public virtual void Execute(Command cmd)
11     {
12 
13     }
14     public virtual bool CanExecute(Command cmd)
15     {
16         return true;
17     }
18    
19 }

然后是各个具体节点的状态类,别看代码这么长,都是些冗长重复的东西。

  1 public class Run : BaseState
  2 {
  3     public Run()
  4     {
  5         StateInfo = "运行";
  6         Console.WriteLine("状态变为运行");
  7     }
  8     public void ToStop()
  9     {
 10         Console.WriteLine("转到停止中...");
 11         Envierment.st = new Stop();
 12     }
 13 
 14     public void ToPause()
 15     {
 16 
 17         Console.WriteLine("转到暂停中...");
 18         Envierment.st = new Pause();
 19     }
 20 
 21     public void Snap()
 22     {
 23         Console.WriteLine("快照中...");
 24         Console.WriteLine("快照完成...");
 25     }
 26 
 27     public override void Execute(Command cmd)
 28     {
 29         //base.Execute(cmd);
 30         if (cmd == Command.ToStop)
 31             ToStop();
 32         else if (cmd == Command.ToPause)
 33             ToPause();
 34         else if (cmd == Command.Snap)
 35             Snap();
 36         else
 37         {
 38 
 39         }
 40     }
 41     public override bool CanExecute(Command cmd)
 42     {
 43         //return base.CanExecute(cmd);
 44         if (cmd == Command.ToStop || cmd == Command.ToPause || cmd == Command.Snap)
 45             return true;
 46         else
 47             return false;
 48     }
 49 
 50 }
 51 
 52 public class Pause : BaseState
 53 {
 54     public Pause()
 55     {
 56         StateInfo = "暂停";
 57         Console.WriteLine("状态变为暂停");
 58     }
 59     public void ToRun()
 60     {
 61         Console.WriteLine("转到运行中...");
 62 
 63         Envierment.st = new Run();
 64     }
 65     public void ToStop()
 66     {
 67         Console.WriteLine("转到停止中...");
 68 
 69         Envierment.st = new Stop();
 70     }
 71 
 72     public void Snap()
 73     {
 74         Console.WriteLine("快照中...");
 75         Console.WriteLine("快照完成...");
 76     }
 77     public override void Execute(Command cmd)
 78     {
 79         //base.Execute(cmd);
 80         if (cmd == Command.ToStop)
 81             ToStop();
 82         else if (cmd == Command.ToRun)
 83             ToRun();
 84         else if (cmd == Command.Snap)
 85             Snap();
 86         else
 87         {
 88 
 89         }
 90     }
 91     public override bool CanExecute(Command cmd)
 92     {
 93         //return base.CanExecute(cmd);
 94         if (cmd == Command.ToStop || cmd == Command.ToRun || cmd == Command.Snap)
 95             return true;
 96         else
 97             return false;
 98     }
 99 }
100 
101 public class Stop : BaseState
102 {
103     public Stop()
104     {
105         StateInfo = "停止";
106 
107         Console.WriteLine("状态变为停止");
108     }
109     public void Start()
110     {
111         Console.WriteLine("转到暂停中...");
112         Envierment.st = new Pause();
113     }
114 
115     public override void Execute(Command cmd)
116     {
117         //base.Execute(cmd);
118         if (cmd == Command.Start)
119             Start();
120         else
121         {
122 
123         }
124     }
125     public override bool CanExecute(Command cmd)
126     {
127         //return base.CanExecute(cmd);
128         if (cmd == Command.Start)
129             return true;
130         else
131             return false;
132     }
133 }

整体使用

如何用?我们的思想是new一个对象出来放那,然后这个实例他就代表了一个全局的状态,状态切换走的时候 我们new新的对象代替,他们都是基于同一个父类,不同子类是否能执行某些状态切换方法在其内部进行,一个类就代表了一个特定类型的节点,如此实现分而治之的效果。初始是stop状态

1 public class Envierment
2 {
3     public static BaseState st;
4     public static void Initial()
5     {
6         st = new Stop();
7     }
8 }
 1 <WrapPanel>
 2             <Button Name="btn_start" Height="25" Width="50" Click="btncmd_Click">启动</Button>
 3             <Button Name="btn_torun" Height="25" Width="50" Click="btncmd_Click">运行</Button>
 4             <Button Name="btn_topause" Height="25" Width="50" Click="btncmd_Click">暂停</Button>
 5             <Button Name="btn_snap" Height="25" Width="50" Click="btncmd_Click">快照</Button>
 6             <Button Name="btn_tostop" Height="25" Width="50" Click="btncmd_Click">停止</Button>
 7         </WrapPanel>
 8         <WrapPanel>
 9             <Label Height="25">当前状态:</Label>
10             <Label Height="25" Name="lab_state">停止</Label>
11         </WrapPanel>
 1 public Window1()
 2 {
 3     InitializeComponent();
 4     Envierment.Initial();
 5     lab_state.Content = Envierment.st.StateInfo;
 6 }
 7 private void btncmd_Click(object sender, RoutedEventArgs e)
 8 {
 9     Button btn = sender as Button;
10     Command cmd = Command.ToStop;
11 
12     if (btn.Name == "btn_start")
13         cmd = Command.Start;
14     if (btn.Name == "btn_torun")
15         cmd = Command.ToRun;
16     if (btn.Name == "btn_topause")
17         cmd = Command.ToPause;
18     if (btn.Name == "btn_snap")
19         cmd = Command.Snap;
20     if (btn.Name == "btn_tostop")
21         cmd = Command.ToStop;
22 
23     Envierment.st.Execute(cmd);
24 
25     if (Envierment.st.CanExecute(Command.Start))
26         btn_start.IsEnabled = true;
27     else
28         btn_start.IsEnabled = false;
29 
30     if (Envierment.st.CanExecute(Command.ToRun))
31         btn_torun.IsEnabled = true;
32     else
33         btn_torun.IsEnabled = false;
34 
35     if (Envierment.st.CanExecute(Command.ToPause))
36         btn_topause.IsEnabled = true;
37     else
38         btn_topause.IsEnabled = false;
39 
40     if (Envierment.st.CanExecute(Command.Snap))
41         btn_snap.IsEnabled = true;
42     else
43         btn_snap.IsEnabled = false;
44 
45     if (Envierment.st.CanExecute(Command.ToStop))
46         btn_tostop.IsEnabled = true;
47     else
48         btn_tostop.IsEnabled = false;
49 
50     lab_state.Content = Envierment.st.StateInfo;
51 }

 

最终的效果

 

标签:Envierment,实现,cmd,else,状态机,所谓,Command,btn,public
From: https://www.cnblogs.com/assassinx/p/17976340

相关文章

  • m基于FPGA的Hamming汉明编译码verilog实现,包含testbench测试文件,不使用IP核
    1.算法仿真效果本系统进行了Vivado2019.2平台的开发,测试结果如下:2.算法涉及理论知识概要在现代数字通信和存储系统中,错误检测和纠正(ErrorDetectionandCorrection,EDC)机制是至关重要的。Hamming码,以其发明者RichardHamming命名,是一种线性错误检测和纠正码,广泛应用于这些系......
  • k8s之基于metallb实现LoadBalancer型Service
    一、实验说明1、实验目的基于metallb实现kubernetes的LoadBalancer型Service。2、环境说明VMwareWorkstation安装三台虚拟机,安装K8S集群,网络模式NAT模式。master11.0.1.131node0111.0.1.132node0211.0.1.133oot@master:/home/user#kubectlgetnodesNAMESTATU......
  • 实现定时任务的六种策略
    这篇文章,我们聊聊实现定时任务的六种策略。1自定义单线程上图中,我们启动一个线程,该线程无限循环执行,每隔20毫秒执行业务代码。这种方式非常简单易用,在很多中间件中得到广泛应用。2JDKScheduleExecutorServiceScheduledExecutorService是Java标准库提供的一个用于调度......
  • 基于SSM的双星小区物业管理系统的设计与实现
    传统办法管理双星小区物业信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装双星小区物业管理系统软件来发挥其高效地信息处理的作用,可以规范双星小区物业信息管理流程,让管理工作可以系统化和程序化,同......
  • 基于SSM的电动车上牌管理系统的设计与实现
    课题背景早在20世纪80年代,美国就已经开始发展电子商务行业,良好的经济,完备的技术和稳定的社会条件,为信息化管理行业的发展提供了一种很好的发展氛围。1999年,为了每一个需要的用户都实现上网,欧盟委员会制定了电子欧洲计划。相比于国外,我国信息化管理出现的比较晚,但是相关的技术人员......
  • python3使用socket模块实现简易syslog服务器
    废话不多说直接上代码1importsocket2importtime345defsocket_bind(server_socket,host,port=514,max_retries=5):6retries=07whileretries<max_retries:8try:9server_socket.bind((host,port))10......
  • 用队列实现栈
      /**@lcapp=leetcode.cnid=225lang=cpp**[225]用队列实现栈*///@lccode=startclassMyStack{public:MyStack(){q1=newqueue<int>;q2=newqueue<int>;}~MyStack(){deleteq1;......
  • 基于SSM的生鲜配送系统设计及实现
    互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对生鲜配送信息管理混乱,出错率高,信息安全性差,劳动强度大,费时费力等问题,采用生鲜配送系统可以有效管理,使信息管理能够更加......
  • 基于html5的演唱会购票系统的设计与实现
    随着信息互联网购物的飞速发展,一般企业都去创建属于自己的电商平台以及购物管理系统。本文介绍了基于html5的演唱会购票系统的设计与实现的开发全过程。通过分析企业对于基于html5的演唱会购票系统的设计与实现的需求,创建了一个计算机管理基于html5的演唱会购票系统的设计与实现的......
  • 用栈实现队列
      /**@lcapp=leetcode.cnid=232lang=cpp**[232]用栈实现队列*///@lccode=startclassMyQueue{public:MyQueue(){}voidpush(intx){s1.push(x);}intpop(){if(s2.empty()){......