设计模式系列之状态模式(5)
在 设计模式系列之状态模式(4) 中介绍了状态机和Stateless开源状态机库。本文通过Stateless来实现 设计模式系列之状态模式(2) 中提到的审批流程。
请假流程图
Stateless实现
直接上代码:
using Stateless;using Stateless.Graph;const string project_manager_audit = "项目经理审批";const string is_over_three = "是否大于3天";const string depart_project_audit = "部门经理审批";const string end_request = "流程结束";const char agree = 'y';const char disagree = 'n';// Instantiate a new state machine in the 'off' statevar stateSwitch = new StateMachine<string, char>(project_manager_audit);// Configure state machine with the Configure method, supplying the state to be configured as a parameterstateSwitch.Configure(project_manager_audit).Permit(agree, is_over_three);stateSwitch.Configure(project_manager_audit).Permit(disagree, end_request);stateSwitch.Configure(is_over_three).Permit(agree, depart_project_audit);stateSwitch.Configure(is_over_three).Permit(disagree, end_request);//无论同意与否,流程都结束stateSwitch.Configure(depart_project_audit).Permit(agree, end_request);stateSwitch.Configure(depart_project_audit).Permit(disagree, end_request);//node [fontname="Microsoft YaHei" shape=Mrecord] 才可以显示中文//dot -T pdf -o request.pdf request.dotstring graph = UmlDotGraph.Format(stateSwitch.GetInfo());Console.WriteLine(graph);Console.WriteLine("Press to toggle the switch. Any other key will exit the program.");while (true){ Console.WriteLine("Switch is in state: " + stateSwitch.State); var pressed = Console.ReadKey(true).KeyChar; // Check if user wants to exit if (stateSwitch.State.ToString().Contains("结束")) break; // Use the Fire method with the trigger as payload to supply the state machine with an event. // The state machine will react according to its configuration. stateSwitch.Fire(pressed);}
运行上面的代码:
上面是不断输入y之后的结果,也可以输入y/n不同组合查看结果。
渲染DOT图像语言
在 设计模式系列之状态模式(4) 有关于dot语言渲染的内容,
啊,竟然是乱码!!
解决乱码
在代码中已经给出解决方案了:
node [fontname="Microsoft YaHei" shape=Mrecord] 才可以显示中文。
添加后可正确显示:
完善代码
将字符串写入到文件中,并且自动执行dot命令。
using Stateless;using Stateless.Graph;using System.Diagnostics;using System.Text;using System.Text.RegularExpressions;const string project_manager_audit = "项目经理审批";const string is_over_three = "是否大于3天";const string depart_project_audit = "部门经理审批";const string end_request = "流程结束";const char agree = 'y';const char disagree = 'n';// Instantiate a new state machine in the 'off' statevar stateSwitch = new StateMachine<string, char>(project_manager_audit);// Configure state machine with the Configure method, supplying the state to be configured as a parameterstateSwitch.Configure(project_manager_audit).Permit(agree, is_over_three);stateSwitch.Configure(project_manager_audit).Permit(disagree, end_request);stateSwitch.Configure(is_over_three).Permit(agree, depart_project_audit);stateSwitch.Configure(is_over_three).Permit(disagree, end_request);stateSwitch.Configure(depart_project_audit).Permit(agree, end_request);stateSwitch.Configure(depart_project_audit).Permit(disagree, end_request);//node [fontname="Microsoft YaHei" shape=Mrecord] 才可以显示中文//dot -T pdf -o request.pdf request.dotstring graph = UmlDotGraph.Format(stateSwitch.GetInfo());//Console.WriteLine(graph);//FileStream fileStream = new("test.dot", FileMode.OpenOrCreate);if (HasChinese(graph)){ Console.WriteLine("包含中文字符"); StringBuilder sb = new(); using (StringReader reader = new(graph)) { string line; while ((line = reader.ReadLine()) != null) { if (line.IndexOf("node") == 0) { sb.AppendLine("node[fontname = \"Microsoft YaHei\" shape = Mrecord]"); } else { sb.AppendLine(line); } } } graph = sb.ToString();}File.WriteAllText(AppDomain.CurrentDomain.BaseDirectory + "request.dot", graph);var result = ExecuteCommand("dot", "-T pdf -o request.pdf request.dot");if (result != 0){ Console.WriteLine("dot error"); return;}Console.WriteLine("Press y/n to toggle the switch. Any other key will exit the program.");while (true){ Console.WriteLine("Switch is in state: " + stateSwitch.State); var pressed = Console.ReadKey(true).KeyChar; // Check if user wants to exit if (stateSwitch.State.ToString().Contains("结束")) break; // Use the Fire method with the trigger as payload to supply the state machine with an event. // The state machine will react according to its configuration. stateSwitch.Fire(pressed);}int ExecuteCommand(string fileName, string parameter){ ProcessStartInfo processStartInfo = new(fileName, parameter); processStartInfo.UseShellExecute = true; processStartInfo.CreateNoWindow = true; //zprocessStartInfo.RedirectStandardOutput = false; Process? process = Process.Start(processStartInfo); process?.WaitForExit(); int result = process.ExitCode; process?.Close(); return result;}/// /// 判断字符串中是否包含中文/// /// 需要判断的字符串/// 判断结果bool HasChinese(string str){ return Regex.IsMatch(str, @"[\u4e00-\u9fa5]");}
参考
https://blog.csdn.net/az9996/article/details/92701884
https://www.cnblogs.com/Herzog3/p/5090974.html
https://vimsky.com/examples/detail/csharp-ex-System.Diagnostics-Process-WaitForExitAsync-method.html
https://blog.csdn.net/qq_39162826/article/details/106018167
https://www.coder.work/article/228548
公众号
更多内容,欢迎关注我的微信公众号:半夏只夜的无情剑客。