Hi, I have a C++ state machine implemented using the State design pattern. Each state is implemented as a nested friend class of the context class.
class Context {
public:
/* The Context class' user calls process1() to get it to perform an action */
void process1();
private:
class IState;
void switchState( IState *newState );
class IState {
virtual void doProcess( Context &context ) = 0;
};
class StateA : public Context::IState {
void doProcess( Context &context );
};
friend class StateA;
class StateB : public Context::IState {
void doProcess( Context &context );
};
friend class StateB;
.
.
.
class StateJ : public Context::IState {
void doProcess( Context &context );
};
friend class StateJ;
};
Currently, a successful iteration of the state machine runs from Context::StateA
to Context::StateJ
when Context::process1()
is called but some of the states contain internal logic to determine whether to loop back to an earlier state. So a typical execution will look like:
StateA
StateB
StateC
StateD
StateE
StateC
StateD
StateE
StateF
StateG
StateH
StateI
StateJ
The internal logic to determine next state is currently being implemented by the respective state itself by storing data in the context object. What I need to do now is add a Context::process2()
option that significantly differs in the order of execution of states. Of course, this can be done using flags that are set in the context object but I was wondering if there is better way to implement this; maybe even use this method to rewrite the handling of state switches within Context::process2()
.
The Visitor design pattern might do the trick but I'm not sure whether its intended for implementing state machines. When using Visitor, process1()
could contain all logic for the order of execution of states and then just call each state in that order. Similarly, process2()
would handle all of its own logic.
Thanks in advance for your answers.
- Ashish.
EDIT:
To those of you that replied saying I should be creating a separate state machine, the reason I'm looking to avoid that is because the code for the states used by the second state machine is identical to those in the first; only the progression is different.
The second state machine will go through the following state transitions:
StateA
StateB
StateC
StateJ
So I'm trying to eliminate duplicated code.