# Why do we need Design Patterns? - Part 2

Part 1: 
[Why do we need Design Patterns? Inheritance isn't enough!!!](https://phamduyhieu.com/why-do-we-need-design-patterns-inheritance-isnt-enough)


So we know using inheritance has not worked out very well, since the duck behavior *keeps* *changing* across the **subclasses**, and it's not appropriate for all **subclasses** to have those behaviors. 

The **Flyable** and **Quackable** interface sounded promising at first - except Java interfaces typically have no implementation code, so **no code reuse**. And whenever you need to modify a behavior, you're often forced to track down and change it in all the different subclasses where that behavior is defined,probably introducing new *bugs* along the way :)))


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629040680710/Olli_iQwp.png)

After a long time, some Godfathers from US or somewhere I don't know, they invented the Design Principle:



![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629040718657/XhdMcx9yu.png)

In other words, **take the parts that vary and encapsulate them, so that later you can alter or extend the parts that vary without affecting those that don't.**

As simple as this concept is, it forms the basis for almost every *design patterns*. All patterns provide a way to let some part of a system vary independently of all other parts.


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629041163768/Jho7E0712.png)

Okay, time to pull the *duck behavior* out of the **Duck** classes!


### Separating what changes from what stays the same

Different from the problems with **fly()** and **quack()**, the **Duck** class is working well and there are no other parts of it that appear to vary or change frequently. So we're going to leave the **Duck** class alone.

**Separate the *parts that change from those that stay the same***

So we create two sets of classes (totally apart from **Duck**), one for *fly* and one for *quack*. Each set of classes will hold all the implementations of the respective behavior. 


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629042305776/C5Gf9q-dC.png)

So how are we going to design the set of classes that implement the fly and quack behaviors?

We know that we want to *assign* behaviors to the instances of **Duck**, instantiate a new **Duck** instance with a specific type of flying behavior and then we want to change the behavior *dynamically*.

Let's look at the second **Design Principle**


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629042517465/cKpEdf5u3.png)

#### Ex: 

- Programming to an implementation:
      

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629043809509/cRHfaf3tWM.png)


- Programming to an interface/superclass:

![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629043897136/EdVj-Xhmr.png)

-----------------------

We'll use an interface to represent each behavior - for instance, **FlyBehavior** and **QuackBehavior** - each implementation of a *behavior* will implement one of those interfaces.


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629042954004/MiXPpu2M-.png)

So this time it won't be the *Duck* classes that will implement the *flying* and *quacking* interfaces. Instead, we create a set of behavior classes.

And a behavior does not come either from a concrete implementation in the superclass **Duck** or by providing a specialized implementation in the *subclass* ifself. So we do not rely on an *implementation*.

With the new design, the actual implementation of the behavior won't be locked into the **Duck** subclass.


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629043987770/tnUGL_hK8.png)

With this design, other types of objects can **reuse** our *fly* and *quack* behaviors because these behaviors are no longer hidden away in our **Duck** classes!

And we can add *new behaviors* without modifying any of our *existing behavior* classes or touching any of the *Duck* *classes* that use *flying behaviors*.

 #### Integrating the Duck Behaviors

** 1. We'll add two instance variables of type FlyBehavior and QuackBehavior**
  
- remove the **fly()** and **quack()** methods from the **Duck** class
- replace them with two similar methods, called **performFly()** and **performQuack()**


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629046624223/b2ThR76wd.png)

**2. Implement performQuack()**


```
public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;

    // rather than handling the quack behavior itself,
    // the Duck object delegates that behavior to the object
    // referenced by quackBehavior
    public void performQuack() {
        quackBehavior.quack();
    }
}
``` 
In this part of code, we don't care what kind of object the concrete Duck is, **all we care about is that it knows how to quack()**.


```
public class VietnamDuck extends Duck {

    // VietnamDuck inherits the quackBehavior and flyBehavior instance variables
    // from class Duck
    public MallardDuck() {
        // use Quack class to handle its quack
        // so when performQuack is called, the responsibility for the quack
        // is delegated to the Quack object
        quackBehavior = new Quack();
        // similar with flyBehavior
        flyBehavior = new FlyWithWings();
    }

    public void display() {
        System.out.println("I'm a real Mallard duck");
    }
}
``` 

It looks good :)) But I said that we *should NOT program to an implementation*, right? But in my constructor, I am making a new instance of a concrete **Quack** implementation class!

Yeah, you can set the duck's behavior type through a setter method on the Duck class, rather than by instantiating it in the duck's constructor. 

So I add two new methods to the **Duck** class


```
    public void setFlyBehavior(FlyBehavior fb) {
        flyBehavior = fb;
    }

    public void setQuackBehavior(QuackBehavior qb) {
        quackBehavior = qb;
    }
``` 

**So just call the duck's setter method.**



## Take a look at a big picture


![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629048519151/s0JP2fk-y.png)


So you can see that **HAS-A** relationship can be better than **IS-A**. Instead of **inheriting** and **implementing** their behavior, the ducks get their behavior by being **composed** with the right behavior object.

This is an important technique, is the basis of our **third design principle**:



![image.png](https://cdn.hashnode.com/res/hashnode/image/upload/v1629048806708/h6g15g0Km.png)

As you've seen, creating systems using composition gives you a lot more flexibility, lets you **change behavior at runtime** as long as the object you're composing with implements the correct behavior interface.

## Summary

Phewww!!! I just applied the Strategy Pattern to solve **code reuse** and **changing requirement** problems. And I showed you that **Inheritance** is not enough to deal with it.

We need **design patterns** to create a software which is ***ready to scale*** and ***easy to maintain***, ***adapt with changes***.

See you in my next post!!















