3

I was reading about the Strategy design pattern in java. The problem is set as follows

You have a duck class and several types of ducks. You have to code in the flying and quacking behaviors of the ducks. You obviously cannot code in the flying, non-flying behaviors in each of the duck class methods especially if you have like a 100 different kind of ducks. So you create a behavior interface called FlyingBehavior and QuackingBehavior and have implementations like NonFlyingBehavior or FlyWithWingsBehavior or MuteQuackBehavior or SqueakQuackBehavior. Then set these in a field in the different classes of duck. That way you associate the behaviors with the ducks.

What I don't understand is why it has to be done with a composition and why not with inheritance. Why can't you create subclasses lke NonFlyingDuck, FlyWithWingsDuck or SqueakingDuck, MuteQuackingDuck and so on, and then implement the methods fly() or quack() and then assign appropriate behavior to the ducks. Is this because multiple inheritance is not supported. so if you have a non-flying, squeaking duck then you cannot extend both squeakingDuck and NonFlyingDuck or is it something else. Is there some way of doing this with inheritance?

I feel a bit confused. The motto is 'favor composition over inheritance'. Why though?

Can someone explain this in depth?

jnovo
  • 5,659
  • 2
  • 38
  • 56
user3490188
  • 499
  • 2
  • 6
  • 14
  • Is this from Head First Design Patterns? In that they have a similar example and all the reasons for the preferred solution. Will put it here when I find it. – Suvarna Pattayil Apr 02 '14 at 16:01
  • I was going to say... did you read the whole book? They explain it really well in Head First Design Patterns – Scott Apr 02 '14 at 16:03
  • it is from Head Fist Design patterns. The problem apparently is multiple inheritance. thanks all for your help. – user3490188 Apr 02 '14 at 16:07
  • In languages that support multiple inheritance, this would be fairly easy to do with inheritance, but in a language like Java where you only get one superclass, you'd have to start making some arbitrary decisions about class hierarchy order. – Joshua Taylor Apr 02 '14 at 16:08
  • You should avoid multiple inheritance anyway - http://stackoverflow.com/questions/406081/why-should-i-avoid-multiple-inheritance-in-c – Scott Apr 02 '14 at 16:09

3 Answers3

0

I don't know about an in-depth explaination but why not using inheritance in this case is easy. Because Java doesn't support multiple inheritance.
Imagine that after creating your 4 classes (NonFlyingDuck FlyWithWingsDuck or SqueakingDuck, MuteQuackingDuck) you need to add another behavior ? (like I don't know, CodingDuck). Well you'll end with 8 classes, 2 for each of your CodingDuckBehavior (there are ducks who know how to and others who don't). But why stop here ? You may have multiple implementations of each behavior which renders inheritance impracticable.
If you can put your hands on Head First Design Patterns, I found their Strategy pattern example really well thought (and it gives you example of what can go wrong going the inheritance path).

m4rtin
  • 2,445
  • 22
  • 34
0

There are a number of reasons, as already discussed at length.

Not having multiple inheritance is often one of them but meaningless compared to others among which I'd emphasize preserving encapsulation: when you extend a class you are breaking encapsulation, and you risk modifying its base behavior which would break the Liskov substitution principle.

So, normally composition is preferred over inheritance and as a rule of thumb if you are in doubt you will usually be better off composing instead of extending.

Here you have another good example summarizing some of the reasons.

Community
  • 1
  • 1
jnovo
  • 5,659
  • 2
  • 38
  • 56
0

If you tried it with inheritance you would end up with far too many types of Duck with an unwieldly structure. How would you define a duck that both quacks and whistles and flies only over the sea along with another type that whistles and does not quack and flies over land etc. etc.

What the customer wants is to be able to create a duck and then define its characteristics by calling methods.

Duck mallard = new Duck();
mallard.setQuacks(true);

Duck teal = new Duck();
teal.setQuacks(true);
teal.setWhistles(true);

They can then build these objects from input data on the fly rather than having to code them all up beforehand.

Obviously you could refine the Duck by subclassing if you like. You could then use a factory to build them:

class SeaDuck extends Duck {
}

The essence of the strategy pattern is that you build the strategy into the code.

public call () {
  // Encode the Strategy.
  if ( quacks ) {
    // Quack.
  }
  if ( whistles ) {
    // Whistle.
  }
}
OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213