C#C
C#13mo ago
Falco

Did I implement State Machine Pattern correctly?

Im trying to implement State Machine Pattern for the state of a form, but I feel like it's not right or adding any convenience.

Context:

User fills in a form on my webpage. User then saves the form. Upon saving, the form should get one of the following states:
c#
 public enum State
    {
        [Description("NewForm")] // Initial state
        Draft = 0,
        [Description("Denied")] // Form was denied
        Afgekeurd = 1,
        [Description("Approved")] // Form was approved
        Afgerond = 2, 
        [Description("WaitForApprovalManager")] // Form needs manager approval
        WaitForApprovalManager = 3,
        [Description("WaitForApprovalTech")] // Form needs tech department approval
        WaitForApprovalTech = 4,
        [Description("WaitForApprovalFinance")] // Form needs finance department approval
        WaitForApprovalFinance = 5,
    }

The state of a form is defined by business rules. For example:
If (form.totalpay < 500) Finance should approve the form state should be.
If (form.totalpay >= 500) Finance and management should approve the form.
If (form.totalpay >= 500 and form = tech) All departments should approve. 
etc..


I made an attempt to make a state machine pattern, but I can't seem to understand why it's useful. So maybe im not doing it correctly. Tips are very welcome.

How I implemented the State Machine Pattern:
FormStateService.cs
c#
public class FormStateService
    {
        private FormState _currentState; // Current state of the form
        private Form _form; // Form that the user filled in
 
        public FormStateService(Form form)
        {
            _form = form;
            if (_currentState == null)
            {
                SetState(new DraftState()); // Set initial state to draft
            }
        }
 
        public void SetState(FormState state)
        {
            _currentState = state;
            _currentState.SetContext(_form);
        }
 
        public Form HandleStateTransition()
        {
            _currentState.HandleStateTransition(this);
            return _form;
        }
 
        public Status GetCurrentState()
        {
            return (State)_form.State;
        }
    }

FormState.cs:
C#
    public abstract class FormState
    {
        protected Form _form;
 
        public void SetContext(Form form)
        {
            _form = form;
        }
 
        public abstract void HandleStateTransition(FormStateService stateMachine);
    }

Each State has its own class like this with the business rules defined. For example this is what each stateclass looks like.
WaitForApprovalManagerState.cs
c#
        public override void HandleStateTransition(FormStateService stateMachine)
        {
 
            if (_form.TotalReceipt >= 500) // Wait for managed to approve
            {
                _form.State = (int)Status.WaitForApprovalManagerState;
        stateMachine.SetState(new WaitForApprovalManagerState());
                return;
            }
 
            if (_form.TotalReceipt >= 500 && _form.ManagerApproved && _form.TechForm == true) // If manager has approved let tech approve
            {
                _form.State = (int)Status.WaitForApprovalTechState;
                stateMachine.SetState(new WaitForApprovalTechState());
                return;
            }
 
        }
Was this page helpful?