1、适用于明确状态流转的场景;
2、由事件推动状态切换;
3、描述 "规则",而非编写 "分支逻辑",流转规则集中收拢,可读性、可维护性大幅提升,复杂业务不会产生 "状态面条代码";
4、新增状态逻辑扩展很容易,代码较集中;
5、OnExit(Async)、OnEnter(Async)、OnEnterFrom(Async)钩子内可轻松完成业务逻辑;
cs
private Order _order;
private void button1_Click(object sender, EventArgs e)
{
_order = new Order() { OrderMoney = 100};
_order.Initialize();
}
private async void button2_Click(object sender, EventArgs e)
{
var state = await _order.PayOrder(59.5M);
if (state == OrderStatus.Paid)
{
button2.Enabled = false;
}
}
private async void button3_Click(object sender, EventArgs e)
{
await _order.Send();
}
private async void button4_Click(object sender, EventArgs e)
{
await _order.Finish();
}
cs
using Microsoft.SqlServer.Server;
using Stateless;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowsFormsApp_Stateless
{
public class Order
{
private StateMachine<OrderStatus, OrderEvent> _stateMachine = new StateMachine<OrderStatus, OrderEvent>(OrderStatus.Created);
public void Initialize()
{
_stateMachine.Configure(OrderStatus.Created)
.OnExitAsync(async (evt) => {
Debug.WriteLine($"订单从{evt.Source}状态跳转到{evt.Destination}状态 Event={evt.Trigger}");
})
.Permit(OrderEvent.Pay, OrderStatus.Paid)
.Ignore(OrderEvent.Send)
.Ignore(OrderEvent.Finish);
_stateMachine.Configure(OrderStatus.Paid)
//.OnExit((evt) => {
// Debug.WriteLine($"订单从{evt.Source}状态跳转到{evt.Destination}状态 Event={evt.Trigger}");
//})
.OnExitAsync(async (evt) =>
{
Debug.WriteLine($"{evt.Source} {evt.Trigger} {_stateMachine.State} 订单已支付,开始生成发货单");
//todo 订单状态切换到Paid,可以执行必要的业务操作,如生成发货单、锁定库存、发送支付通知等
})
.Permit(OrderEvent.Send, OrderStatus.Shipped)
//.OnExit((evt) => {
// Debug.WriteLine($"订单从{evt.Source}状态跳转到{evt.Destination}状态 Event={evt.Trigger}");
//})
.Ignore(OrderEvent.Finish);
_stateMachine.Configure(OrderStatus.Shipped)
.OnEntryAsync(async (evt) =>
{
Debug.WriteLine($"{evt.Source} {evt.Trigger} {_stateMachine.State} 订单已发货");
//todo 订单状态切换到Shipped,可以执行必要的业务操作,如...等
})
.Permit(OrderEvent.Finish, OrderStatus.Completed);
_stateMachine.Configure(OrderStatus.Completed)
.OnEntryAsync(async (evt) =>
{
Debug.WriteLine($"{evt.Source} {evt.Trigger} {_stateMachine.State} 订单已完成");
//todo 订单状态切换到Shipped,可以执行必要的业务操作,如...等
});
}
public OrderStatus GetOrderStatus() => _stateMachine.State;
public decimal OrderMoney { get; set; }
public List<(DateTime time, string log, decimal payMoney)> PayLog = new List<(DateTime time, string log, decimal payMoney)>();
public async Task<OrderStatus> PayOrder(decimal money)
{
var payMoney = Math.Min(OrderMoney, money);
PayLog.Add((DateTime.Now, $"第{PayLog.Count}次支付{payMoney}元,剩余{OrderMoney - payMoney}元", payMoney));
OrderMoney -= payMoney;
if (OrderMoney == 0)
await _stateMachine.FireAsync(OrderEvent.Pay);
return _stateMachine.State;
}
public async Task Send()
{
await _stateMachine.FireAsync(OrderEvent.Send);
}
public async Task Finish()
{
await _stateMachine?.FireAsync(OrderEvent.Finish);
}
}
public enum OrderStatus
{
Created = 0,
Paid,
Shipped,
Completed
}
public enum OrderEvent
{
Pay,
Send,
Finish
}
}