Strategy Design Pattern

The Strategy Pattern is a behavior pattern. Whereas an algorithm or class can be changed during run time execution. To employ this pattern, we develop a set of classes that provide implementation strategies and a context object whose behavior is varied based a given strategy object. The strategy object changes the context object’s executing algorithm.

Plainly put, the overall idea is the encapsulation of behavior via objects, allowing us to invoke a desired behavior based on a given criteria, state, or external input. More importantly, this design prevents the implementation of large conditional statements or introducing an anti-pattern.

The Scenario
We will attempt to model this pattern against a mock security system. Let us assume that we have been tasked to implement a design that allows for any number of alert messaging mechanisms, e.g., Cellular, Web, SMS etc.

Possible Implementation – Conditional Logic
Typically, one might attempt to employ the use of conditional logic such as if/else or switch statements. The path chosen could be based on a config file, or some other external input.

However, this approach can easily get out of hand as the need for additional message types grows.

Challenges´╗┐

Conditional logic requires more tests. When added to an already existing code base, we’ll have to ensure that the existing logic is not broken as well.

Over time the source will become less maintainable and possibly more difficult to understand.

Another Implementation – Inheritance

One also might choose to create an Abstract Class and derive classes that would implement the necessary algorithms required.

Advantages

The choice here is superior to implementing conditional logic. As the use of inheritance in this manner supports the Open Closed Principal – “Software entities should be open for extension, but closed for modification.” With the goal being to extend an entity’s behavior via extension without modifying its existing code.

In addition, this type of implementation results in less tests to write. The code is also more maintainable as compared to a conditional logic based implementation.

Challenges

However, in the event we are tasked in the future to add additional methods to the base abstract class. There is the risk of child objects possibly inheriting unnecessary methods of which may not make sense for those objects.

Therefore, by forcing objects to implement methods that are not needed indicates a design flaw and is a design smell.

Implementing Our Strategy

We are going to implement a strategy interface that defines an action with concrete classes that implement that strategy interface. The context class is the class that uses the strategy.

First, we will setup the Strategy Interface

Next, we will implement each Concrete class. Each class will implement its own version of messaging.

Now we will add the Context calls which uses composition object as a reference to our Strategy.

To ensure that our Strategy is working as expected. We can implement a series of simple tests.

Summary

Refactoring to the Strategy Pattern can produce benefits in situations where a part of the system is governed by rules; in which case, multiple strategies may be required.

Moreover, this patterns allows for different algorithms to be employed for a given situation. In addition to providing an easy path towards testing each strategy separately as a result of encapsulation.

Leave a Reply

RSS
Twitter