- Forwarding Engine States
- Modeling a Generic State
- Getting the State Engine Started
- The Forwarding EngineRunning All the States
- Pattern Extensibility
- Conclusion
- Additional Reading
Getting the State Engine Started
The simplest state is the one that starts the forwarding engine. Listing 3 illustrates the InitialState class—the first subclass of the State base class to create an initial state subclass for the program.
Listing 3 The InitialState Class
class InitialState : public State { public: static InitialState* Instance(); virtual char* whatCanWeDo(void); explicit InitialState(); private: static InitialState m_InitialState; };
The InitialState class derives from State and—in typical object-oriented fashion—adds a few bits and pieces along the way. The member function Instance() returns an instance of the InitialState class. As it turns out, this is the one and only instance of this class—the so-called singleton design pattern. (see reference [2] in the "Additional Reading" section).
Listing 4 illustrates the implementation of the Listing 3 interface.
Listing 4 Implementation of the InitialState class
InitialState InitialState::m_InitialState; InitialState::InitialState() { } char* InitialState::whatCanWeDo(void) { return "STATE CAPABILITIES: Move to the forwarding state or exit\n"; } InitialState* InitialState::Instance() { return &m_InitialState; }
Listing 4 illustrates the Instance() method returning a pointer to a static instance of the InitialState class. The whatCanWeDo() method illustrates the capabilities of this state—you can move from the initial state to the forwarding state or the exit state.
To begin, let’s have a look at the ForwardingState class (see Listing 5).
Listing 5 ForwardingState class
#include "ForwardingState.h" ForwardingState ForwardingState::m_ForwardingState; ForwardingState::ForwardingState() { } char* ForwardingState::whatCanWeDo(void) { return "STATE CAPABILITIES: Forward data or move to the exit state\n"; } ForwardingState* ForwardingState::Instance() { return &m_ForwardingState; }
Notice the similarity between the ForwardingState class and InitialState class. The only major differences between these two states lies in their capabilities. The latter can be arbitrarily complex, but the underlying model is still simply that of a state! And, the only thing you can do with a state is enter it, do some work, and then exit it.
Last but not least, Listing 6 illustrates the ExitState class interface.
Listing 6 ExitState class interface
#ifndef EXIT_STATE_H #define EXIT_STATE_H #include "State.h" class State; class ExitState : public State { public: static ExitState* Instance(); virtual char* whatCanWeDo(void); explicit ExitState(); private: static ExitState m_ExitState; }; #endif
No big surprises in Listing 6; as expected, it’s also very similar to InitialState.
Listing 7 illustrates the implementation of the ExitState class.
Listing 7 ExitState class implementation
#include "ExitState.h" ExitState ExitState::m_ExitState; ExitState::ExitState() { } char* ExitState::whatCanWeDo(void) { return "STATE CAPABILITIES: Move to the initial state or exit the program\n"; } ExitState* ExitState::Instance() { return &m_ExitState; }
You’ve now seen all the code segments in isolation. So, let’s complete the picture and put them all together.