Strategy Pattern

Nitin Verma
7 min readJan 19, 2019

So this is the first pattern in my Design pattern series. Before reading this story make sure that you have read Introduction to design patterns.

Prerequisite:

  1. Again make sure that you have read Introduction to design patterns.
  2. You understand java or any other OOP language
  3. you have basic idea about inheritance,polymorphism,interfaces
  4. you find my stories interesting 😉
Photo by Nikita Kostrykin on Unsplash

Suppose that you are developing a new game. let’s call it Napalm 🔥 (cool name..?)

Now Napalm is all about fighting. For now assume that they can move, run and tell who they are. You designed 4 characters : Wizard, Giant, Golem and Harry.

As we are good with OOPS principles so we will use inheritance. Let’s make a superclass Fighter. All other characters classes such as wizard,giant,etc will inherit from it(as they all are fighters !). All characters move and run in same fashion so we will provide common implementation of these methods in fighter class and every child class will inherit it and we will override displayName method in each child class so that they tell it properly who they are. Our design will be similar to this:

UML like diagram (initial design)

Everything looks good and you are adding more features in Napalm. You have a crazy idea to add a new power to throw fire🔥 !!
You decided to give this power to harry and wizard.
How hard it can be to implement it 😌? You just need to add fire method in Fighter class. Your new design will be:

added fire power

Now you have fire power inherited into wizard and harry.

Wizard ron=new Wizard();
ron.fire(); // and ron will fire
// similarly with object of harry class

But wait there is a major problem !! When we added fire method in Fighter class(parent) then all of it’s chil classes will inherit. Note that not all characters have all powers. some can fly while some can’t, some can throw fireballs while some can’t(sensitive skin issues 😶) but now golem and giant also has fire power(this is not what we want).
When we added fire method in parent class, it was great use of inheritance for the purpose of code reuse but not so well when it comes to maintenance. Moreover what if we want different types of fire powers in different characters? Let’s say wizard can throw fire balls and harry can shoot a fire laser. Adding a single implementation in supercalss won’t let us do this. we will have to override the method and provide implementation in every character class.

Solution 1 : we can override fire method in other sub-classes to do nothing, this way only wizard and harry will get fire power. But this solution is not good in the long run. Think about it, soon we will add new characters in our game and new powers will also be added for some of them. If we continue with this approach then we’ll have to remember to override and do nothing for all new powers in all children classes. Our second problem of having different behaviors of fire power still remains.

Solution 2 : you might be thinking about it for a while. As we want only certain characters to get a new power we can also use interfaces. Only certain classes will implement a interface and override the methods. So we’ll make a FirePowerInterface.java interface in which we will have a fire method and Wizard, harry classes will implement this interface and implement the methods of interface. This way both of our problems are solved:

  1. fighters such as golem don’t have fire power
  2. wizard can throw fireballs and harry can shoot fire beam

Here’s our new design :

Solid lines means extends and dotted lines mean implements.

using interface

But wait now we have a even bigger problem !! By using interfaces we are not reusing our code. Every class who implement this interface will have to override the methods and provide implementation. Second problem is that it will be really hard to introduce changes. In future let’s say if we want to change the fire power (eg: it’s color or damage or range or any other implementation part) then we will have to go to every class which implements this interface and make same changes several times which makes our code not maintainable.

Can you think of some other approach to solve our problem? Grab a cup of coffee and think about it. Just take a break, as now I want your full attention.

Come back soon !

We know that fire() is the part of Fighter class which vary across various various fighters. so we’ll pull out this method and create a new set of classes to represent each fire behavior. This way, the character classes won’t need to know any of the implementation details for their own behaviours. Now instead of defining fire method in it’s own class, Fighters will delegate it’s fire behavior. Here’s our set of classes that represent fire behaviors:

fire behavior

Wiring up :

First we will add a instance variable in Fighter class named fireBehavior of interface type.

FireBehavior fireBehavior;

Each Fighter object will set this variable during instantiation. Advantage of making this variable of interface type(and not a particular class) is that we will be able to able to set it in a polymorphic way at run time(more on this later). We will also make a new method in Fighter class named performFire(). Rather than handling the fire behavior itself, object will delegate the behavior to the object referenced by fireBehavior. we don’t care what kind of object it is, all we care is that it knows how to fire !

public void fireBehavior(){ 
fireBehavior.fire();
}

Our wizard class will look like this:

Our Fighter class will look like this:

Here’s our FireWithBalls.java class where our our implementation of fire() method will live

//now wizard can fire like this:
Wizard obj = new Wizard();
obj.performFire();
//that's all !!

now only change that we need to make in Harry class will be that it’s fireBehavior will be initialized with FireNoWay.

We have following advantages by doing things like this:

  1. character who can’t fire won’t be able to fire as their fireBehavior will be initialized with FireNoWay.
  2. if we need to change something with the implementation of fire power(let’s say related to fire with laser) then we have to make changes at only one place (ofcourse in FireWithLaser’s overloaded fire method !)
  3. We can change fire behavior dynamically. we are going to do this with few lines of code. but before it, let’s discuss why would we need to do it? Suppose that in our game whenever a character reaches a score of 100(or it’s multiple) then he gets a special power(ummm…let’s say fire bomb whose code is in FireWithBomb.java class…a new class,, you got the pattern). Now whenever this happens we need to change fireBehavior from whatever it is to FireWithBomb. now let’s add this functionality also.

Setting behavior dynamically:

add a new method in Fighter class

public void setFireBehavior(FireBehavior fb){
fireBehavior=fb;
}

with just these lines of code, we can change fire behavior dynamically.

Wizard obj = new Wizard();
obj.performFire(); // will fire with balls
obj.setFireBehavior(new FireWithBomb());
obj.performFire(); // now he will throw fire bombs

Here’s our new design:

added fire behavior

If you have read this far then you have done a great job ! yeahhhh party time. But wait golem and giant are not happy with you as you have not given them any power. Let’s give them a punch power. Golem have mega-punch power and giant have….ummm…. giant-punch power 😉. can you add this new puch behavior all by yourself? try it yourself and see our new updated design:

added punch behavior

Conclusion:

Now think of each set of behaviors as a family of algorithms(see dig below). Note that we have used composition. Each fighter HAS-A fire behavior and punch behavior to which it delegated fire and punch. Remember to favor composition over inheritance. As you have seen, creating systems using composition gives you a lot more flexibilit. It not only let’s us encapsulate a family of algorithms into their own set of classes, but it also allowed us to change behavior at runtime.

Now let’s also cover the formal definition of Strategy pattern:

The strategy pattern defines a family of algorithms, encapsulates each one, and make them interchangeable. Strategy let’s the algortithm vary independently from the client that uses it.

You can learn the terminology and theory on google also. I tried to explain it through a example. Hope you liked it.

Clap 👏 , Comment and share your valuable feedback and don’t forget to ask more questions in comment section below (if you have any 😉) ✌️

References:
- Head first design patterns book.

--

--

Nitin Verma

Android developer, GIS, writer, Punjabi who love to share knowledge ✌️