在程序的设计过程中,我们经常会遇到一些需要使用状态机的场景,相信状态机的编写和维护是令每一个程序员都非常头大的事情。到了C# 5.0后,由于引进了await语法糖,我们可以通过await和Reactive Extensions库来简化这一过程,实现非常直观的状态机。
下面我就以一个简单的门的状态机为例:
-
该门有两种状态,关闭和推开。
-
支持两种操作:推和拉。
-
在关闭的时候只接收推操作,变成推开状态
-
在推开的时候只接收拉操作,变成关闭状态
这个例子我很久以前实现过,原文地址:C# 3.0下有限状态机的一种优雅的实现,当时还是C# 3.0,现在在C# 5.0中,我们可以以一种更为优雅的方式来实现他:。
enum Operation { Push, Pull }
class
Door
{
Subject<Operation> operationEvent;
public Door()
{
operationEvent = new
Subject<Operation>();
ProcessAsync();
}
public
void Process(Operation op)
{
operationEvent.OnNext(op);
}
async
void ProcessAsync()
{
while (true)
{
//初始门是关闭的
await operationEvent.Where(i => i == Operation.Push).FirstAsync();
Console.WriteLine("门被推开了");
//进入推开状态
await operationEvent.Where(i => i == Operation.Pull).FirstAsync();
Console.WriteLine("门被拉上了");
}
}
}
在await语法糖和RX库的辅助下,类似同步的方式实现的状态机非常直观,我们甚至连状态变量都可以给省掉了,比之前的实现要简洁不少,也能更加容易的实现复杂的状态逻辑。