In this post I will explain how you can implement the Strategy pattern using Design by Contract without violating the DRY (Donâ??t Repeat Yourself) principle. The strategy pattern can be used to expose algorithms which are interchangeable and can vary without the client even knowing it. Design by Contract is a programming method where you define contracts for functions with pre and post conditions.
The violation of the DRY principle occurs when you are implementing the strategy pattern, The abstract base class of the strategy defines a pure virtual/abstract function. The concrete strategy implementation class, â??Aâ??, implements the function. When you implement the function you need to write code for the pre and post condition checks. The problem occurs when you need to implement another strategy implementation class â??Bâ??. Again you need to write the pre and post condition code. That is a clear violation of the DRY principle as well as wrong implementation of the strategy pattern: because it states that all the strategies should behave in the same way, although it is not a violation, programmers might write exactly the same code twice, but it does not rule out the possibility.
Now that I have defined the problem it is time to look at the solution. The solution is quite simple and looks really neat in my humble opinion.
First you need to create a new base class for all the strategy implementation classes: The class contains two methods: One public sealed/final function which is used by the client and one protected abstract/pure virtual function which is used for the actual strategy implementation. The signature of the two function must be exactly the same.
The public function performs three steps, run the pre conditions, call the strategy implementation function and run the post conditions. The protected abstract/pure virtual function is implemented in the concrete strategy classes. The class now looks like this:
public abstract class AbstractStrategy
{
public void Perform()
{
// pre condition code
// call actual algorithm
ExecPerform();
// post condition code
}
protected abstract void ExecPerform();
}
This code does implement strategy pattern correctly, guarantees that the pre and post conditions are run exactly the same for all concrete strategies and does not contain any duplicate code: smart, logical and beautiful.