The Notion of State
State-specific code is no longer restricted solely to special-purpose applications such as compilers and eCommerce web sites. It can be incorporated easily and advantageously into application code. Code written to the state design pattern can be structured in a very modular fashion—you just create a new state and add it to the application when you’re ready. In this way, your application becomes a series of distinct states. This approach potentially facilitates team environments as well as individual efforts. Adding state support in C++ is relatively easy—and, as usual with design patterns, the benefits are substantial.
The notion of state is extremely important in computing. In some ways, state has often been handled in passing by application software; for example, so-called wizards present a fairly fixed notion of state as the user moves through the various stages. In other areas, such as telecom, state is everything—when you make a phone call, for instance, your actions dictate the state transitions of the call from start to finish. Inside the network, your actions of dialing a number, talking, and eventually hanging up are actually causing the instantiation and control of complex state machine code. The notion of state is also very important in web transactions, particularly the financial variety. Another area where state modeling is a key ingredient is workflow software.
In this article, I use the state design pattern to illustrate how to add state management to your C++ code. The model I use involves an eCommerce engine that provides a number of states. User interaction allows for controlled state transitions through multiple phases:
- Initial state.
- Purchase state.
- Exit state.
- Program termination.
Each state presents a finite set of capabilities—when you’ve dialed a phone number, you don’t start to talk until someone answers or a voice mail diversion occurs. In other words, the post-dial state presents a few options: wait or hang up. As we’ll see, this is an interesting and powerful model because it allows us to break a program into a series of states. The main logic then dictates the transitions between these states.
The modeling of state transitions is an increasingly important area of computing. As we all engage in more online transactions, just imagine what it might be like if computational states weren’t properly maintained. To illustrate, let’s assume that you’re buying some shares online. Imagine you’re a budding Warren Buffett and you’re waiting for the price to drop. You place a limit order to buy at a reduced price, only to find that the order has already been placed at the higher price because the state management code has a bug! In this article, I show how easy it is for state to be modeled using the state design pattern.
Listing 1 shows a sneak preview of the finished code, where we do the following:
- Create an eCommerce engine entity in its initial state.
- Determine and print the state-specific capabilities of the engine.
- Change from the initial state to the purchase state.
- Get and print the state-specific capabilities of the engine again.
Listing 1 Implementation of the command pattern.
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());
As Listing 1 shows, the engine provides the ability to do the following:
- Interrogate the engine capabilities.
- Change states.
We’ll see more on this later.