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

实现一个状态机

时间:2024-01-28 21:02:28浏览次数:22  
标签:Envierment 实现 cmd else 状态机 一个 Command btn public

问题的描述

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

 

实现一个状态机_Click

 

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

实现

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

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 }

 

最终的效果

实现一个状态机_ide_02

实现一个状态机_Click_03

实现一个状态机_Click_04

 



标签:Envierment,实现,cmd,else,状态机,一个,Command,btn,public
From: https://blog.51cto.com/u_9571691/9454201

相关文章

  • 用Java语言实现一个观察者模式
    观察者模式(也被称为发布/订阅模式),提供了避免组件之间紧密耦合的另一种方法,它将观察者和被观察的对象分开。在该模式中,一个对象通过添加一个方法(该方法允许另一个对象,即观察者注册自己)使本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。这些观察者收到消......
  • 卷积神经网络详解+Python实现卷积神经网络Cifar10彩色图片分类
    原文链接:https://blog.csdn.net/master_hunter/article/details/133156758卷积神经网络相对于普通神经网络在于以下四个特点:局部感知域:CNN的神经元只与输入数据的一小部分区域相连接,这使得CNN对数据的局部结构具有强大的敏感性,可以自动学习到图像的特征。参数共享:在CNN中,同一个......
  • 基于Basic auth 的一个C# 示例
    最近在做公司的一个项目时,客户需要我们定时获取他们矩阵系统的数据。在与客户进行对接时,提到他们的接口使用的目前不常用的BASIC认证。天呢,它好不安全,容易被不法人监听,咋还在使用呀。但是没办法呀,谁让客户的系统就是这样的呢。因为现在开发中绝大多数使用的是基于Bearer认证的。......
  • 基于OpenIM 实现聊天机器人功能
    ###简要描述使用OpenIM中的Webhook机制实现聊天机器人功能。发送文本消息或图片消息给聊天机器人后,机器人会返回相同的消息。开发者可以替换此逻辑,在LangChain框架上调用LLM接口(包括gpt3.5或其他开源本地模型),以实现智能客服功能。##1.修改配置文件参照下面的模板修改op......
  • 如何使用Python实现图像识别?
    原文链接:https://blog.csdn.net/qq_61433567/article/details/1311398481OpenCV(OpenSourceComputerVisionLibrary):用于图像处理和计算机视觉方面的函数库。2NumPy:用于处理数组和矩阵。3Matplotlib:用于绘制图像和图表。可以使用以下命令来安装这些库:pipinstallopencv-python......
  • 读论文-基于Python的协同过滤算法的研究与应用实现
    前言今天读的论文为一篇名为《基于Python的协同过滤算法的研究与应用实现》的论文,文章是在2019年9月发表于《电脑知识与技术》的一篇期刊论文。摘要随着科学技术的快速发展和知识产权的日益重要,大多数用户会选择在播放平台上看电影。例如腾讯视频、爱奇艺等,用户迫切需要一个合......
  • Python 实现 zip 分卷解压
    在上传数据备份到云端的时候,由于数据文件过大,可能会遇到各种各样的问题:比如49G的大文件gitlfspush到99%突然失败,你说心态爆炸不爆炸?再比如某些网盘会限制单个文件上传大小限制在4G以内;因此我们可能会用7z之类的压缩软件对数据文件进行分卷压缩,得到多个分卷文件,例如......
  • 如何管理好一个一盘散沙的新团队?
    如何管理好一个一盘散沙的新团队?**面对这样一道大题:很多人都在谈人,但缺少事人是管不住的;很多人都只关心方法,但真正能让80%的人通过80%的努力达到80分的不是方法,而是方法论!**如何盘活并管理好一个一盘散沙的新团队?或许“六步走”的方法论,才能帮助局中人找到捉刀的正确思路与姿势。......
  • C语言代码实现:三子棋小游戏
    //game.h#pragmaonce#include<stdio.h>#include<stdlib.h>#include<time.h>#defineROW3#defineCOL3//初始化棋盘voidInitBoard(charboard[ROW][COL],introw,intcol);//声明//打印棋盘voidDisplayBoard(charboard[ROW][COL],introw,intco......
  • 维吉尼亚c语言实现加解密
    #include<stdio.h>#include<stdlib.h>#include<ctype.h>#include<string.h>#include<time.h>#defineOK 1#defineERROR 0typedefstructDualNode{intdata;structDualNode*prior;structDualNode*next;......