state design pattern

This commit is contained in:
Claudiu Farcas
2021-04-28 12:22:15 +03:00
parent 6b6a491a99
commit a5852b780d
3 changed files with 135 additions and 1 deletions
+3 -1
View File
@@ -20,6 +20,7 @@ using design_patterns.behavioral.iterator;
using design_patterns.behavioral.mediator; using design_patterns.behavioral.mediator;
using design_patterns.behavioral.memento; using design_patterns.behavioral.memento;
using design_patterns.behavioral.observer; using design_patterns.behavioral.observer;
using design_patterns.behavioral.state;
namespace design_patterns namespace design_patterns
{ {
@@ -53,7 +54,8 @@ namespace design_patterns
// await IteratorSample.Run(); // await IteratorSample.Run();
// await MediatorSample.Run(); // await MediatorSample.Run();
// await MementoSample.Run(); // await MementoSample.Run();
await ObserverSample.Run(); // await ObserverSample.Run();
await StateSample.Run();
} }
catch (System.Exception ex) catch (System.Exception ex)
{ {
+128
View File
@@ -0,0 +1,128 @@
using System;
using System.Threading.Tasks;
using Stateless;
namespace design_patterns.behavioral.state
{
/// <summary>
/// State is a behavioral design pattern that lets an object
/// alter its behavior when its internal state changes.
/// It appears as if the object changed its class.
///
/// Use it when:
/// - you have an object that behaves differently depending
/// on its current state, the number of states is enormous,
/// and the state-specific code changes frequently.
/// - you have a class polluted with massive conditionals
/// that alter how the class behaves according to the current values
/// of the classs fields.
/// - you have a lot of duplicate code across similar states
/// and transitions of a condition-based state machine.
///
/// easy to use STATELESS nuget package
/// https://www.nuget.org/packages/stateless
/// https://github.com/dotnet-state-machine/stateless
/// </summary>
public class StateSample
{
public static async Task Run()
{
Console.WriteLine("Behavioral - State");
var machineOrder = BuildMachine();
var trigger =OrderTrigger.CreateOrder;
machineOrder.Fire(trigger);
System.Console.WriteLine($"state: {machineOrder.State}");
if(machineOrder.State != OrderState.New)
System.Console.WriteLine($"Error with order state trigger {trigger} - state {machineOrder.State}");
trigger =OrderTrigger.RegisterOrder;
machineOrder.Fire(trigger);
System.Console.WriteLine($"state: {machineOrder.State}");
if(machineOrder.State != OrderState.Registered)
System.Console.WriteLine($"Error with order state trigger {trigger} - state {machineOrder.State}");
// // once cancelled it cannot migrate to other sates
// trigger = OrderTrigger.CancellByCustomer;
// machineOrder.Fire(trigger);
// System.Console.WriteLine($"state: {machineOrder.State}");
trigger = OrderTrigger.BeginProcessing;
machineOrder.Fire(trigger);
System.Console.WriteLine($"state: {machineOrder.State}");
trigger = OrderTrigger.Packaging;
machineOrder.Fire(trigger);
System.Console.WriteLine($"state: {machineOrder.State}");
trigger = OrderTrigger.Shipping;
machineOrder.Fire(trigger);
System.Console.WriteLine($"state: {machineOrder.State}");
trigger = OrderTrigger.Delivering; // or .ReturnByCustomer or .ReturnByShipment
machineOrder.Fire(trigger);
System.Console.WriteLine($"state: {machineOrder.State}");
}
public static StateMachine<OrderState, OrderTrigger> BuildMachine() {
var machineOrder = new StateMachine<OrderState, OrderTrigger>(OrderState.New);
// from new to draft
machineOrder.Configure(OrderState.New)
.PermitReentry(OrderTrigger.CreateOrder)
.Permit(OrderTrigger.SaveAsDraft, OrderState.Draft)
.Permit(OrderTrigger.RegisterOrder, OrderState.Registered);
// from draft to registered
machineOrder.Configure(OrderState.Draft)
.Permit(OrderTrigger.RegisterOrder, OrderState.Registered);
// from registered to cancelled or begin processing
machineOrder.Configure(OrderState.Registered)
.Permit(OrderTrigger.CancellByCustomer, OrderState.Cancelled)
.Permit(OrderTrigger.BeginProcessing, OrderState.Processing);
// from processing to cancelled of packaging
machineOrder.Configure(OrderState.Processing)
.Permit(OrderTrigger.CancellBySupplier, OrderState.Cancelled)
.Permit(OrderTrigger.Packaging, OrderState.Packaged);
// from packaged to shipped or return
machineOrder.Configure(OrderState.Packaged)
.Permit(OrderTrigger.Shipping, OrderState.Shipped)
.Permit(OrderTrigger.ReturnByShipment, OrderState.ReturnedByShipment);
// from shipped to
machineOrder.Configure(OrderState.Shipped)
.Permit(OrderTrigger.Delivering, OrderState.Completed)
.Permit(OrderTrigger.ReturnByShipment, OrderState.ReturnedByShipment)
.Permit(OrderTrigger.ReturnByCustomer, OrderState.ReturnedByCustomer);
return machineOrder;
}
public enum OrderState {
New,
Draft,
Registered,
Processing,
Packaged,
Shipped,
Completed,
// other states
Cancelled,
ReturnedByShipment,
ReturnedByCustomer
}
public enum OrderTrigger {
CreateOrder,
SaveAsDraft,
RegisterOrder,
CancellByCustomer,
CancellBySupplier,
BeginProcessing,
Packaging,
Shipping,
Delivering,
ReturnByShipment,
ReturnByCustomer
}
}
}
+4
View File
@@ -5,4 +5,8 @@
<TargetFramework>net5.0</TargetFramework> <TargetFramework>net5.0</TargetFramework>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<PackageReference Include="stateless" Version="5.11.0" />
</ItemGroup>
</Project> </Project>