Strategy Design Pattern

Tushar Kumar
5 min readMay 18, 2021

According to Wikipedia:

In computer programming, the strategy pattern (also known as the policy pattern) is a behavioral software design pattern that enables selecting an algorithm at runtime. Instead of implementing a single algorithm directly, code receives run-time instructions as to which in a family of algorithms to use

The above doesn’t make a lot of sense if you are a beginner in the field of Design Pattern. So we will understand the Strategy Design Pattern in this article in more simpler and easier language.Let’s start!

Let’s follow the discussion which is happening between Shyam and his client:

Client: Hi Shyam! I have headphone company and would like to make an app for it

Shyam: Hi! Yes sure, May I know what kind of headphones you make?

Client: We make Bluetooth based headphones and would like a software for charging purpose

Shyam: Worry no more! I will make it happen.

Shyam goes to his office and starts coding this software. His idea of implementation is that, he will make an abstract class called as Headphones and declare a method in it called as charging() and connect(). Now every headphone which the company makes, will extend this class.

Each of the the class which extends the Headphones class will have their own implementation of connect() and charge() method. Currently the company has only 2 headphones namely HeadphoneA and HeadphoneB

Shyam delivered this software to the client and went out for party! After few days of happiness, he got a call from the client.

Client: Hi Shyam! The application you delivered to us is working perfectly!

Shyam: That’s great to hear!

Client: By the way, we have introduced a new line of headphones which can be connected to devices through 3.5mm Jack and doesn’t need any charging too! Isn’t that great?! We would like to add these headphones to our software.

Shyam: Hmm…Let me get back to my thinking chair..

Did you realize how much mess we are in now?! If not, let’s deep dive into the tsunami of problems which this new requirement bought with itself!

Problem 1:

The new class which we create for Non-Bluetooth headphones can extend our Abstract Headphone class. We can keep the charging() method empty. But this solution is not good as in future there could be, let’s say 50 headphones. which are not Bluetooth, hence do not need any charging() method. All of these methods are needed to kept with empty implementation.

Inheritance does not seem like a good idea then as it makes accessible all the methods to all of its sub-classes. In such cases, if a set of class does not need a particular method, then we are forced to keep them as blank implementation

Problem 2:

You could argue that we can only use those methods in the Abstract class/Interface which are common to all the classes and keep the class specific methods in their individual classes. This approach has one issue. Code re-usability. Let’s suppose there is a bunch of classes which has common code. And there are also a bunch of classes which do not use these common code. In that case, we cannot put it in the abstract class/Interface and we are forced to implement the same code in all of the classes which uses it.

Problem 3:

Again on the lines of code re-usability,if the same code is written at multiple places, what if the behavior of the piece of code is changed in future? We need to track down all the uses of that code in our entire code base and make that change. This results in wastage of a lot of time and a huge maintenance nightmare.

If the behavior of a common piece of code changes, then we need to make such changes in the individual classes. There is no provision of changing the behavior of classes at runtime as the class itself needs to be modified

To tackle such problems, the Strategy Pattern is found to be very useful.

Strategy Pattern says that we identify the code in our code base which has a possibility of changing and encapsulate it at any other place apart from our context class

Let’s understand the above statement with the help of our example. In our case, the behavior of charging could be different for different headphones. So we take this behavior and encapsulate it. This can be done by making a new interface called as ChargingBehavior and have individual classes implementing it according to their own requirement.

We will add the Interface in our context class to support the runtime change in the algorithm if we wanted. In this way we are using the concept of composition instead of Inheritance.

The above changes in strategy will bring us the following advantages:

Advantage 1:

Using the Interface and its corresponding implementation classes helps to make our code more flexible. Let’s suppose today, our code base uses one implementation of the interface, tomorrow it may so that there is a new implementation and we want to use that. In that case we do not have to make any changes in our classes, we will simply plug-in the new class from the place where we call that class’s method.

Advantage 2:

Earlier we discussed about code re-usability and how using an abstract class simply will hinder our code re-usability intent. Using interface, this problem can be completely solved. One set of behavior can be re-used in the context classes and the code snippets which are used uniformly across every implementation of the interface can take advantage of default implementation of a method in the interface. In this way we are following the DRY principle

So our final implementation will follow the following principles:

1.)Prefer composition over inheritance.

2.)Always code to the interface and never to the concrete classes.

--

--