Famn
Famn

Reputation: 33

Clarification required - Design Patterns

In most of the design patterns concepts, it was mentioned that "Has A" is better than "Is A" means.

In the first chapter - Head First Design Patterns - "Intro to Design Patterns", section "Integrating the Duck Behaviour" (page no 15), the Duck class is having references to FlyBehavior and QuackBehavior interface types. For example, we are going to add a new behavior in feature name it XYZBehavior (just assume client has not yet decided it) for one kind of Ducks, we need to change the Duck class to have the reference to new interface. Resulting, we need to alter the class but which should not happen according to good design pattern.

Can you suggest me how can we deal with this requirement?

Upvotes: 3

Views: 194

Answers (3)

Ravindra babu
Ravindra babu

Reputation: 38910

You can handle this scenario by using Composition => Duck has a list of Behaviours.

Duck will maintain a list of Behaviour objects. Populate relevant behaviours during creation of Duck object.

Sample code:

import java.util.*;

interface Behaviour{

}
class FlyBehaviour implements Behaviour{

}
class QuackBehaviour implements Behaviour{

}
class XYZBehaviour implements Behaviour{

}

public class Duck{
    private List<Behaviour> duckBehaviours = new ArrayList<Behaviour>();

    public Duck(List<Behaviour> list){
        duckBehaviours = list;
    }
    public static void main(String[] args){
        // set the behaviours
        List<Behaviour> list = new ArrayList<Behaviour>();
        list.add(new FlyBehaviour());
        list.add(new QuackBehaviour());
        list.add(new XYZBehaviour());
        Duck duck = new Duck(list);
    }   
}

Upvotes: 0

Andreas Dolk
Andreas Dolk

Reputation: 114787

The Strategy pattern does not prevent from changing the class if you add a new behaviour (strategy). It just prevents from touching the class, if an existing behaviour (strategy) changes.

Example with QuackBehaviour: assume, we thought, a duck would sound like "quaack" but after some years of research we realised, that ducks actually sound like "quaaack". We're lucky, we implemented a QuackBehaviour and just adjust the implemtation of the QuackBehaviour interface for common ducks. That's the trick with this pattern.

If later on, we decide to add a SwimBehaviour, because another research team realized, that swimming is a common duck behaviour, then we have to touch the common duck and add that behaviour (to the Duck class).

Hope it helped!

Upvotes: 0

Sean Patrick Floyd
Sean Patrick Floyd

Reputation: 298938

That problem can be solved by using Dependency Injection

(In Java usually through either Spring or Guice)

Here's a Beginner's Guide to dependency Injection

Basically, a Bird would have a behaviors property:

private Collection<Behavior> behaviors;
public void setBehaviors(Collection<Behavior> behaviors){
    this.behaviors = behaviors;
}

Now in a Configuration file you would specify which Behaviors get injected into the Bird without having to change the Bird class.

Upvotes: 1

Related Questions