C# 3.0下有限状态机的一种优雅的实现
2007-12-27 23:56
225 查看
C# 3.0下有限状态机的一种优雅的实现
实现状态机有多种模式,其中最灵活而强大的方式是通过迁移表来实现,该方式的缺点之一是需要编写大量小块代码去支持迁移表。而在C#3.0中,可以以一种非常优雅的方式实现。
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()
{
//正常操作
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
{
rule[State][op]();
}
catch (KeyNotFoundException)
{
Console.WriteLine(string.Format("门在{0}状态下不允许{1}操作", State, op));
}
}
}
}
从代码中可以看到,通过lambda表达式,可以简化迁移表的构造,并且更加直观。
通过迁移表构造状态机的一种不足在于查询速度,在本例中每个操作都要进行两次查询才能进行状态转换操作。如果状态较多则非常费时,这里我把它改进了一下,使得每次操作只需要查询一次即可。
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));
}
}
}
实现状态机有多种模式,其中最灵活而强大的方式是通过迁移表来实现,该方式的缺点之一是需要编写大量小块代码去支持迁移表。而在C#3.0中,可以以一种非常优雅的方式实现。
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()
{
//正常操作
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
{
rule[State][op]();
}
catch (KeyNotFoundException)
{
Console.WriteLine(string.Format("门在{0}状态下不允许{1}操作", State, op));
}
}
}
}
从代码中可以看到,通过lambda表达式,可以简化迁移表的构造,并且更加直观。
通过迁移表构造状态机的一种不足在于查询速度,在本例中每个操作都要进行两次查询才能进行状态转换操作。如果状态较多则非常费时,这里我把它改进了一下,使得每次操作只需要查询一次即可。
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));
}
}
}
相关文章推荐
- C# 3.0下有限状态机的一种优雅的实现【转】
- C# 3.0下有限状态机的一种优雅的实现
- C# 3.0下有限状态机的一种优雅的实现
- C/S模式在线升级之C#一种实现(一)
- [Delphi] XE2下实现标准的3DES加解密一种方法(可与Java,c#互通)
- 关于有限状态机的一种程序实现结构
- CLR via C# 读书笔记 3-1 一种单实例应用程序的实现(信号量)
- C# ASP.NET B/S模式下,采用lock语法 实现多用户并发产生不重复递增单号的一种解决方法技术参考
- 一种C#的插件式实现(二)_从dll中读取插件信息
- C#中一种替换switch语句更优雅的写法
- (转)C#的委托机制的C++的一种实现
- C/S模式在线升级之C#一种实现(一)
- 一种c#深拷贝方式完胜java深拷贝(实现上的对比分析)
- 一种c#深拷贝方式完胜java深拷贝(实现上的对比)
- C#中实现读/写文件(一种常用的方法)...
- c#实现程序启动唯一实例的一种方法
- C# ASP.NET B/S模式下,采用lock语法 实现多用户并发产生不重复递增单号的一种解决方法技术参考
- 一种多线程基于计数无锁实现(C#)(转载)
- C# 验证码的一种实现
- C# ASP.NET B/S模式下,采用lock语法 实现多用户并发产生不重复递增单号的一种解决方法技术参考