When using state pattern, one is delegating behaviour of the Entity
to the current State
. I have prepared SSCCE that I pasted below. We have an Entity
which can transition between states : StartState
, StateA
, StateB
, EndState
. The happy path is simply the shortest path between StartState
and EndState
.
In this particual example the shortest happy path is: StartState->StateA->StateB->EndState
I find it hard to express what is the happy path, so I can return the order to the frontend but also be able to navigate myself through. State pattern uses methods not dicitonaries to store nodes end edges, right? I want to avoid just List<string>
. I'm looking for an elegant solution.
I want to be able to know upfront what is the order of the states in the happy path.
- Dynamically calculate the shortest path for that class structure? XOR
- Because dynamic calculation is probably hard or very hacky, what is the most elastic/convienient to use way to describe statically the shortest happy path in this state graph?
namespace States
{
public class Entity
{
public int Id { get; private set; }
public State CurrentState { get; private set; }
public void Action1() => CurrentState = CurrentState.Action1() ?? CurrentState;
public void Action2() => CurrentState = CurrentState.Action2() ?? CurrentState;
public void Action3() => CurrentState = CurrentState.Action3() ?? CurrentState;
}
public abstract class State
{
protected Entity _entity;
public State(Entity entity)
{
_entity = entity;
}
//They return new state or null if transition is illegal
public abstract State Action1();
public abstract State Action2();
public abstract State Action3();
}
public class StartState : State
{
public StartState(Entity entity) : base(entity) { }
public override State Action1() => new StateA(_entity); //moves workflow forward
public override State Action2() => null;
public override State Action3() => null;
}
public class StateA : State
{
public StateA(Entity entity) : base(entity) { }
public override State Action1() => null;
public override State Action2() => new StateB(_entity); //moves workflow forward
public override State Action3() => new StartState(_entity); // goes back to StartState
}
public class StateB : State
{
public StateB(Entity entity) : base(entity) { }
public override State Action1() => new EndState(_entity); //moves workflow forward to EndState
public override State Action2() => null;
public override State Action3() => new StartState(_entity); // goes back to StartState
}
public class EndState : State
{
public EndState(Entity entity) : base(entity) { }
public override State Action1() => null;
public override State Action2() => null;
public override State Action3() => null;
}
}
Aucun commentaire:
Enregistrer un commentaire