You are on page 1of 9

State Design Pattern

Stateless (an open source state machine in C#)


State Design Pattern
The intent of the State design pattern is to:
"Allow an object to alter its behavior when its internal state changes. The object
will appear to change its class." [GoF]
Implementation
There are two ways in which we can model states:
● States are actual classes with behaviors, and these behaviors cause the
transition from this state to another. In other words, a state’s members are the
options in terms of where we can go from that state.
● States and transitions are just enumerations. We have a special component
called a state machine that performs the actual transitions.
States are actual classes with behaviors
States and transitions are just enumerations
enum State string code = "1234";
var state = State.Locked;
var entry = new StringBuilder();
{
while (true)
{
Locked, switch (state)
{
case State.Locked:
Failed, entry.Append(Console.ReadKey().KeyChar);

if (entry.ToString() == code)
Unlocked {
state = State.Unlocked;
break;
} }

if (!code.StartsWith(entry.ToString()))
{
// the code is blatantly wrong
state = State.Failed;
}
break;
case State.Failed:
Console.CursorLeft = 0;
Console.WriteLine("FAILED");
entry.Clear();
state = State.Locked;
break;
case State.Unlocked:
Console.CursorLeft = 0;
Console.WriteLine("UNLOCKED");
return;
}
}
C# Switch Expressions
enum Chest { Open, Closed, Locked }
enum Action { Open, Close }

static Chest Manipulate(Chest chest,


Action action, bool haveKey) =>
(chest, action, haveKey) switch
{
(Chest.Closed, Action.Open, _) => Chest.Open,
(Chest.Locked, Action.Open, true) => Chest.Open,
(Chest.Open, Action.Close, true) => Chest.Locked,
(Chest.Open, Action.Close, false) => Chest.Closed,
_ => chest
};
State Machines with Stateless

https://github.com/dotnet-state-machine/stateless

Create state machines and lightweight state machine-based workflows directly


in .NET code:

var phoneCall = new StateMachine<State, Trigger>(State.OffHook);

phoneCall.Configure(State.OffHook)

.Permit(Trigger.CallDialled, State.Ringing);
State Machines with Stateless (continued)
phoneCall.Configure(State.Connected)

.OnEntry(t => StartCallTimer())

.OnExit(t => StopCallTimer())

.InternalTransition(Trigger.MuteMicrophone, t => OnMute())

.InternalTransition(Trigger.UnmuteMicrophone, t => OnUnmute())

.InternalTransition<int>(_setVolumeTrigger, (volume, t) => OnSetVolume(volume))

.Permit(Trigger.LeftMessage, State.OffHook)

.Permit(Trigger.PlacedOnHold, State.OnHold);
Stateless feature
● Entry / Exit actions
● Guard clauses
● Parameterized Triggers
● Reentrant

You might also like