The C++ Strategy Pattern for Multiple Network Events
As software evolves, there is a growing need for more responsive solutions. This is responsiveness in terms of what might be called liveness instead of performance. The shrinking cost of hardware means that there is generally scope for adding extra RAM and more servers. So, in some respects the issue of pure performance can to a certain point be improved by just spending more on hardware. Creating highly responsive solutions is another matter altogether. For superior responsiveness you really need asynchronous support.
Ajax is a good example of this trend toward asynchronous support. It’s a real drag when an entire web page is reloaded after just a small section has changed and Ajax is designed to help in such cases. Just the part that’s changed gets reloaded, saving on bandwidth and user time.
Network technology tends to lag behind front-end developments, but the requirements of both areas are increasingly converging. This applies to responsiveness as well as performance. In this article, I’ll look at a way in which the so-called strategy pattern can be applied to network management. In the same way as the state design pattern helps avoid long sequences of if-else statements in classes, the strategy pattern helps to compartmentalize class-specific handler code.
The example I use is based on the code from an earlier article on the chain of responsibility pattern (see [1] in the "Additional Reading" section). You can see the way the problem of strategy is conceptually similar to the chain of responsibility. It also illustrates the way to mix and match patterns to produce better solutions.
The Takeaway
Listing 1 provides a sneak preview of the finished code, in which I create some network entities and then simulate the occurrence of some network events. For each event, I invoke the event handler chain to see which entity should manage the event. Each entity is configured to handle a specific set of events, so if an incoming event matches, the appropriate entity calls its handler. If no match is found, the event is handed off to the next entity on the chain. In this context, the handler methods implement the strategy design pattern.
Listing 1 Implementation of the strategy pattern in conjunction with the chain of responsibility pattern
Connection* connection = new Connection(CONGESTION); Lsp* lsp = new Lsp("LSP123", connection, LINK_1_BROKEN); Path* path = new Path(lsp, LINK_2_BROKEN); //A network event has occurred, e.g., CONGESTION //Let’s see who can handle this event cout << "Let’s simulate a network error: CONGESTION\n"; path->HandleEvent(CONGESTION); //Another network event has occurred, e.g., LINK_1_BROKEN //Let’s see who can handle this event cout << "Let’s simulate another network error: LINK_1_BROKEN\n"; path->HandleEvent(LINK_1_BROKEN);
Let’s now quickly cover some details about the problem domain.