在程序的設計過程中,我們經常會遇到一些需要使用狀態機的場景,相信狀態機的編寫和維護是令每一個程序員都非常頭大的事情。到了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庫的輔助下,類似同步的方式實現的狀態機非常直觀,我們甚至連狀態變量都可以給省掉了,比之前的實現要簡潔不少,也能更加容易的實現復雜的狀態邏輯。