Базовая настройка конечного автомата с использованием Stateless
У меня есть довольно простые государственные потребности (пока). Я думаю, что я хотел бы смоделировать их с помощью API без сохранения состояния. (Но я не очень разбираюсь в конечных автоматах, поэтому могу ошибаться.)
Но я попал в терминологию (в частности, состояние и триггер)
Вот пример: у меня есть класс заказа. Это настроено с несколькими состояниями. Это: Новый, Заполненный, Отгрузка, Завершенный, Отмененный.
Несколько простых правил состояния, которые мне бы хотелось, чтобы эти переходы состояний были разрешены:
- Новый (по умолчанию)
- Новый -> Заполненный
- Новое -> Отменено
- Заполнено -> Доставка
- Заполнено -> Отменено
- Заполнено -> Доставка
- Доставка -> Завершено
Так, где я здесь споткнулся, каков мой "Триггер"?
На всякий случай, если нужен более конкретный пример, скажем, я хочу такой метод:
public bool UpdateOrderStatus(int OrderId, OrderStatusEnum NewOrderStatus)
это вернет истину, если статус обновился успешно. Как можно настроить и использовать Stateless, чтобы это произошло?
1 ответ
Машина находится только в одном состоянии одновременно; состояние, в котором оно находится в любой момент времени, называется текущим состоянием. Он может переходить из одного состояния в другое, когда инициируется инициирующим событием или условием, это называется переходом. из конечного автомата в вики
Я полагаю, триггер - это запускающее событие.
Обновить:
Конечно, имя триггера иногда может совпадать с некоторыми именами состояний.
New (initial state)
New -> Filled (trigger "Filled")
New -> Cancelled (trigger "Cancelled")
Filled -> Shipping (trigger "ToBeShipped")
Filled -> Cancelled (trigger "Cancelled")
Shipping -> Complete (trigger "Completed").
Обновить:
лица без гражданства действительно хорошая структура! Я пытался реализовать функциональность.
Состояния:
public enum State
{
New,
Filled,
Shipping,
Cancelled,
Completed
}
Триггеры:
public enum Trigger
{
Filled,
Cancelled,
ToBeShipped,
Completed
}
Класс заказа:
public class Order
{
private readonly StateMachine<State, Trigger> _stateMachine;
public Order()
{
_stateMachine = CreateStateMachine();
}
public bool TryUpdateOrderStatus(Trigger trigger)
{
if (!_stateMachine.CanFire(trigger))
return false;
_stateMachine.Fire(trigger);
return true;
}
public State Status
{
get
{
return _stateMachine.State;
}
}
private StateMachine<State, Trigger> CreateStateMachine()
{
StateMachine<State, Trigger> stateMachine = new StateMachine<State, Trigger>(State.New);
stateMachine.Configure(State.New)
.Permit(Trigger.Filled, State.Filled)
.Permit(Trigger.Cancelled, State.Cancelled);
stateMachine.Configure(State.Filled)
.Permit(Trigger.ToBeShipped, State.Shipping)
.Permit(Trigger.Cancelled, State.Cancelled);
stateMachine.Configure(State.Shipping)
.Permit(Trigger.Completed, State.Completed);
stateMachine.OnUnhandledTrigger((state, trigger) =>
{
Console.WriteLine("Unhandled: '{0}' state, '{1}' trigger!");
});
return stateMachine;
}
}
Тестер для Класса заказа:
Order order = new Order();
bool result = order.TryUpdateOrderStatus(Trigger.Completed);
Console.WriteLine("Attemp to complete order: {0}", result);
Console.WriteLine("Order status: {0}", order.Status);
result = order.TryUpdateOrderStatus(Trigger.ToBeShipped);
Console.WriteLine("Attemp to ship order: {0}", result);
Console.WriteLine("Order status: {0}", order.Status);
result = order.TryUpdateOrderStatus(Trigger.Cancelled);
Console.WriteLine("Attemp to cancel order: {0}", result);
Console.WriteLine("Order status: {0}", order.Status);