There are plenty of articles covering this pattern, here I will try to cover the same from a perspective which I believe has helped me really understand what this pattern has to offer. I will try not to throw the pattern at you with all its rules but instead show you how one would end up using it, while correcting few erroneous design choices on the way.
One of the major benefits of object oriented programming is code reuse.
Inheritance is widely used to achieve this reuse, as it allows for defining the common behaviour and properties in a super class which all subclasses then inherit. BUT the problem with inheritance is with its overuse.
Check the below example which shows how certain requirement changes can lead to complications in an inheritance based design.
Now let’s look at few of the issues with inheritance as depicted with the above design choices:
- You can’t change the behavior at runtime.
- Super class behavior when changed will impact across all subclasses.
- Not all subclasses may want the behavior of super class thus end up with duplicated code such as empty overrides or their own custom implementations which can’t be reused by other subclasses.
- With above point, its hard to gain an understanding of all subclass by looking at a super class alone.
Could interfaces have helped?
It could solve some part of the problem, but would not allow for any reuse of code. As each implementing subclass would provide their own implementation.
A more elegant solution can be achieved using a strategy pattern which promotes few design principles as well.
Definition: Strategy pattern defines a family of algorithms, encapsulates each one and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Let’s see how a revised design using the pattern would make our code much more flexible.
The above solution is a lot more flexible and still allows for code reuse!
Here’s few code snippets of how the pattern appears in Java where subclass can set a different behavior: