简体   繁体   中英

How to implement the State design pattern?

Let's say I am going to implement (in the C++) following finite state machine consisting of 5 states where the transitions between the states occur based on value of 6 boolean flags. In each of the states only a couple of the total number of the boolean flags is relevant eg in the State_A the transition into the State_B is conditional by following condition: flag_01 == true && flag_02 == true and the value of the rest of the flags is irrelevant.

在此处输入图像描述

I would like to exploit the State design pattern for implementation of the state machine在此处输入图像描述

I have unfortunately stuck at the very beginning. Namely on definition of the interface of the common base class for all the state subclasses. It seems to me that my situation is little bit different from the examples mentioned in the literature where the state transitions occur based on single events with a guard condition. Can anybody give me an advice how to define the interface for the common base class in my situation where the transitions between states occur based on logic expressions with several operands?

You can create some reducer which will decide what state should be user. Let me show an example via C#.

This is an abstraction of state:

public interface IAtmMachineState
{
    void Execute();
}

and its concrete states:

public class WithdrawState : IAtmMachineState
{
    public void Execute()
    {
        Console.WriteLine("You are taking money");
    }
}

public class DepositState : IAtmMachineState
{
    public void Execute()
    {
        Console.WriteLine("You are putting money");
    }
}

public class SleepState : IAtmMachineState
{
    public void Execute()
    {
        Console.WriteLine("Insert your card");
    }
}

and this is context of state:

public class AtmStateContext
{
    private IAtmMachineState _currentState;

    public AtmStateContext()
    {
        _currentState = new SleepState();
    }

    public void SetState(IAtmMachineState currentState)
    { 
        _currentState = currentState;
    }

    public void Execute() 
    {
        _currentState.Execute();
    }
}

And this is a reducer which can take parameters:

public class StateReducer
{
    public IAtmMachineState Get(int a, string b) 
    {
        if (a == 0)
            return new WithdrawState();
        else if (!string.IsNullOrEmpty(b))
            return new DepositState();

        return new SleepState();
    }
}   

And it can be used like this:

AtmStateContext atmState = new AtmStateContext();
StateReducer stateReducer = new StateReducer();

atmState.SetState(stateReducer.Get(1, ""));
atmState.Execute(); // OUTPUT: insert your card

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM