# The underrated Strategy Design Pattern

# Introduction

We are all too familiar with the *Singleton* and *Observable* design patterns. Yet, there is the so-called *Strategy Design Pattern*, which is quite useful but unknown to many developers. This design approach is a very nice example of the favoring composition over inheritance principle, which means: whenever possible aggregate classes instead of simply adding methods to be inherited.

To better explain this design pattern, and the meaning of favoring composition of inheritance, an example will be used, showing first a not-so-good approach, which will then be replaced by a code using the *Strategy Design Pattern*. Java is the language of choice, but the code is quite simple and can be easily understood even if the reader is not familiar with such language.

# The naive implementation

Our problem consists of modeling superheroes and showing their abilities. So, the first class to be presented, is the `Superhero` abstract class. It has concrete methods, such as `puch()` and `kick()`, and it has a abstract one called `introduceMyself()` which every *Superhero* implementation must fill in. Below the class implementation is displayed:

```
public abstract class Superhero {

  public void punch() {
    System.out.println("punch!!");
  }

  public void kick() {
    System.out.println("kick!!");
  }

  public abstract void introduceMyself();

``` 
The next step, is to implement the `Superhero` abstract class. Therefore we have `Superman`, `Wonderwoman`, `Batman` and `Robin`. As an example, `Batman` implementation is shown below:

``` 
public class Batman extends Superhero {

  @Override
  public void introduceMyself() {
    System.out.println("My name is Batman!!");
  }
}
``` 
In order to see the superheroes showing their powers, they are instantiated and and have their abilities being displayed in as follows:

```
public class AbilitiesDisplay {

  public static void main(String [] args) {
    showSuperheroAbility(new Superman());
    showSuperheroAbility(new Batman());
    showSuperheroAbility(new Robin());
    showSuperheroAbility(new Wonderwoman());
  }

  private static void showSuperheroAbility(Superhero superHero) {
    superHero.introduceMyself();
    superHero.punch();
    superHero.kick();
    System.out.println("________________");
  }
}
``` 
The output of the `main()` method execution is:

``` 
My name is Superman!
punch!!
kick!!
________________
My name is Batman!!
punch!!
kick!!
________________
My name is Robin!
punch!!
kick!!
________________
My name is Wonderwoman!
punch!!
kick!!
________________
``` 

For a better overview, please check the class diagram below:


![naiveimplementation.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1592696631225/AKeKAFT-z.png)

# Let's complicate things

So far, so good. Code is being reused, and it seems that this is indeed a good design. But then, it is decided that our superheroes must also show their ability to fly. No problem, let's add one more method to the `Superhero`. However, note that `Superman` and `Superwoman` do fly in the same manner, whereas `Batman` and `Robin` do not fly at all. By using this approach we start having some code duplication. The implementation from `Superman` and `Wonderwoman` is: 

``` 
@Override
  public void fly() {
    System.out.println("I am flying!!!");
  }
``` 

And the implementation for *Batman* and *Robin* is:

``` 
@Override
  public void fly() {
    System.out.println("I cannot fly!");
  }
``` 

Next, the class diagram provides visual argument for how duplication is occuring regarding the `fly()` method:


![naiveimplementationWithFlyMethod.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1592696774385/doGaFLYDS.png)

To make things worse, imagine there are 50 Heroes where a few can fly and some others cannot. The amount of duplicated code would be immense.  On top of that, there might be other methods to be added with the same issues, like: `fireEyeLaser()` or `becomeInvisible()`.

# A better approach

Instead of implementing every single new ability, what if we code this in separate classes, which the only concern is to produce these new superpowers such as flying or becoming invisible. Then, those classes would be aggregated to the superheroes implementation. Besides *favoring composition over inheritance*, we would *separate what changes from what stays the same*, another very nice principle. An example will clarify this idea.

We will have fly and invisibility behaviors defined by the interfaces `FlyAbility` and `Invisibility` ability, as shown below:

``` 
public interface FlyAbility {
  void fly();
}
``` 

``` 
public interface InvisibilityAbility {
  void becomeInvisible();
}
``` 

`FlyAbility` will have two implementations: `SuperFastFly` and `NoFlyingPossible`, as shown below:

``` 
public class SuperFastFly implements FlyAbility {
  @Override
  public void fly() {
    System.out.println("I can fly pretty fast!!!");
  }
}
``` 

``` 
public class NoFlyingPossible implements FlyAbility {
  @Override
  public void fly() {
    System.out.println("I cannot fly at all!!!l");
  }
}
``` 

`Invisibility` also has two implementations: `InvisibilityPossible` and `InvisibilityPossible`, as displayed next:

``` 
public class InvisibilityPossible implements InvisibilityAbility {
  @Override
  public void becomeInvisible() {
    System.out.println("I am invisible!");
  }
}
``` 

``` 
public class InvisibilityImpossible implements InvisibilityAbility {
  @Override
  public void becomeInvisible() {
    System.out.println("I cannot be invisible!!");
  }
}
``` 

Now, here comes the *gotcha*. instead of the `Superhero` class simply providing  abilities methods to be implemented, such as `fly()` and `becomeInvisible()`, it will hold references to interfaces of `FlyAbility` and `InvisibilityAbility`. These interfaces are responsible for, with their implementations, provide the new abilities, when a `Superhero` implementation is instantiated. Therefore, the `Superhero` does not force its children to implement these behaviors, but rather assign an implementation to them via a `FlyAbility` and `InvisibilityAbility` implementation using composition. In other words, we are aggregating abilities, not inheriting them. Below is displayed how `Superhero` is implemented:

``` 
public abstract class Superhero {

  protected FlyAbility flyAbility;

  protected InvisibilityAbility invisibilityAbility;

  public void punch() {
    System.out.println("punch!!");
  }

  public void kick() {
    System.out.println("kick!!");
  }

  public void performFly() {
    flyAbility.fly();
  }

  public void becomeInvisible() {
    invisibilityAbility.becomeInvisible();
  }

  public abstract void introduceMyself();
}
``` 

As mentioned, references to the `FlyAbility` and `InvisibilityAbility` are held, and their implementations will be executed by the methods `performFly()` and `becomeInvisible()` respectively. Their implementation will be instantiated in each `Superhero` child. Superman is an example depicted below:

``` 
public class Superman extends Superhero {
  @Override
  public void introduceMyself() {
    System.out.println("My name is Superman!");
  }

  public Superman() {
    flyAbility = new SuperFastFly();
    invisibilityAbility = new InvisibilityImpossible();
  }
}
``` 
Observe that `Superman` has the ability to fly, with the `SuperFastFly` instantiation of the `flyAbility` property, but cannot be invisible, since the class instantiates the `InvisibilityImpossible` class as its `invisibilityAbility` parameter.

Compare the `Superman` implementation above, with the naive solution provided before, but displayed here again:

```
public class Superman extends Superhero {

  @Override
  public void fly() {
    System.out.println("I am flying!!!");
  }

  @Override
  public void introduceMyself() {
    System.out.println("My name is Superman!");
  }
}
```

In the naive solution above, the `fly()` method is part of the `Superhero` specification. Note, that here the method is implemented whereas in the *Strategy implementation*, the an instance of a Fly algorithm is used - `SuperFastFly`. This Fly implementation, and many others can be easily used in each `Superhero` implementation. Observe how elegant the *Strategy Design Pattern* is.

Below is displayed all other *Strategy implementations*:

```
public class Superman extends Superhero {
  @Override
  public void introduceMyself() {
    System.out.println("My name is Superman!");
  }

  public Superman() {
    flyAbility = new SuperFastFly();
    invisibilityAbility = new InvisibilityImpossible();
  }
}
```

```
public class Batman extends Superhero {
  @Override
  public void introduceMyself() {
    System.out.println("My name is Batman!!");
  }

  public Batman() {
    flyAbility = new NoFlyingPossible();
    invisibilityAbility = new InvisibilityImpossible();
  }
}
```

```
public class Robin extends Superhero {
  @Override
  public void introduceMyself() {
    System.out.println("My name is Robin!");
  }

  public Robin() {
    flyAbility = new NoFlyingPossible();
    invisibilityAbility = new InvisibilityImpossible();
  }
}
```
Note, how all heroes use the new abilities in a similar fashion: by instantiating each ability in the `Superhero` related parameter.  Continuing, the class below shows our heroes abilities being showcased:

```
public class AbilitiesDisplay {

  public static void main(String [] args) {
    showSuperheroAbility(new Superman());
    showSuperheroAbility(new Batman());
    showSuperheroAbility(new Robin());
    showSuperheroAbility(new Wonderwoman());
  }

  private static void showSuperheroAbility(Superhero superHero) {
    superHero.introduceMyself();
    superHero.punch();
    superHero.kick();
    superHero.performFly();
    superHero.becomeInvisible();
    System.out.println("________________");
  }
}
```
Note that nothing was changed in  `AbilitiesDisplay` except for the new abilities. 

Below the result of the above `main()` method execution, which shows the expected results:

```
My name is Superman!
punch!!
kick!!
I can fly pretty fast!!!
I cannot be invisible!!
________________
My name is Batman!!
punch!!
kick!!
I cannot fly at all!!!l
I cannot be invisible!!
________________
My name is Robin!
punch!!
kick!!
I cannot fly at all!!!l
I cannot be invisible!!
________________
My name is Wonderwoman!
punch!!
kick!!
I can fly pretty fast!!!
I am invisible!
```
And finally the class diagram of the presented solution:

![strategyimplementation.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1592777135549/nTBgeUmfZ.png)

# Strategy Desgin Pattern definitions

Here are a few definitions of this design patterns:

From [Wikipedia](https://en.wikipedia.org/wiki/Strategy_pattern): 
> 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.

From [Head First Design Patterns](https://www.oreilly.com/library/view/head-first-design/0596007124/) 
> The 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.

# A few last words

Note how using the *Strategy Design Pattern*, code reuse is beautifully applied. The abilities in our example, can be used easily in each instantiation of the `Superhero` class. Moreover, adding new behavior is easily achieved by providing another ability reference. Furthermore, another very nice side effect is that things that change, such as the abilities, are separated from the *main code* -  superhero class and its children - which serves well the principle: *separate what changes from what stays the same*.

You can find the complete source code [here](https://github.com/dufernandes/blogs-rouce-code/tree/master/hashnode/articles/strategyDesignPattern).
