- The Notion of State
- Online Commerce
- States Involved in a Transaction
- Modeling a State
- Getting into a State
- The eCommerce Engine: Bringing All the States Together
- Pattern Extensibility
- Conclusion
The eCommerce Engine: Bringing All the States Together
Listing 8 illustrates the interface for the ECommerceEngine class.
Listing 8 The ECommerceEngine class.
#include "State.h" #include "PurchaseState.h" #include "InitialState.h" #include "ExitState.h" class ECommerceEngine { public: explicit ECommerceEngine(void); virtual ~ECommerceEngine(void); friend class State; void changeState(State*); char* getStateCapabilities(); private: State* _state; };
The interface in Listing 8 includes all of the state-specific header files we’ve already reviewed. In addition, it declares the State class to be a friend. This gives the ECommerceEngine class privileged access to the State class and its members. The ECommerceEngine class also implements the changeState() member function that allows it to explicitly change the current state. This allows for the state transitions we saw in Figure 2. The getStateCapabilities() member is familiar now—it indicates the state capabilities. Finally, the ECommerceEngine class provides a data member called _state that keeps track of the current state.
Let’s look at the implementation of the ECommerceEngine class in Listing 9.
Listing 9 Implementation of the ECommerceEngine class.
ECommerceEngine::ECommerceEngine(void) { _state = NULL; changeState(InitialState::Instance()); } char* ECommerceEngine::getStateCapabilities(void) { return _state->whatCanWeDo(); } ECommerceEngine::~ECommerceEngine(void) { } void ECommerceEngine::changeState(State* pState) { if (pState != _state) { _state = pState; } }
In Listing 9, we see that the ECommerceEngine constructor initializes the _state data member to NULL as well as setting the initial state to that provided by a call to changeState(InitialState::Instance()). This call reaches into the InitialState and sets the operating state accordingly. The getStateCapabilities() method calls into the whatCanWeDo() member function associated with the _state data member. The changeState() method is fairly self-explanatory—it simply updates the state as required. Instantiation of the ECommerceEngine class is done in the main() function as illustrated in Listing 10 (see Figure 3).
Listing 10 Instantiating an object of the ECommerceEngine class.
int _tmain(int argc, _TCHAR* argv[]) { ECommerceEngine* myECommerceEngine = new ECommerceEngine(); printf(myECommerceEngine->getStateCapabilities()); printf("Now in the initial state\n"); printf("Let’s go buy some stuff - moving to the purchase state\n"); myECommerceEngine->changeState(PurchaseState::Instance()); printf(myECommerceEngine->getStateCapabilities()); printf("No money left, better move into the exit state\n"); myECommerceEngine->changeState(ExitState::Instance()); printf(myECommerceEngine->getStateCapabilities()); delete myECommerceEngine; return 0; }
Figure 3 Running the complete program.
Listing 10 is the unabbreviated version of the code in Listing 1. In Listing 10, we see an instance of ECommerceEngine being created. At this point, the capabilities of this state are displayed. We know that we’re in the initial state at this stage, so, as the two printf() statements show, we can now move into the purchase state. Once in the purchase state, we again record the state capabilities. We stay in this state until we spend all of our money, at which point we move to the exit state. We then record the state capabilities again before deleting the instance of ECommerceEngine and exiting the program.
Clearly, at each state we have a set of capabilities that change as we move into other states.