This week's giveaway is in the Android forum.
We're giving away four copies of Android Security Essentials Live Lessons and have Godfrey Nolan on-line!
See this thread for details.
The moose likes OO, Patterns, UML and Refactoring and the fly likes HFDP - Strategy Pattern Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Engineering » OO, Patterns, UML and Refactoring
Bookmark "HFDP - Strategy Pattern" Watch "HFDP - Strategy Pattern" New topic
Author

HFDP - Strategy Pattern

Brian Smith
Ranch Hand

Joined: Oct 26, 2002
Posts: 232
Hello Folks,
just read through the first chapter. great presentation! however, i still have a few concerns i would like clarification on -

Based on "seperate what changes from what stays the same" principle fly() and quack() behaviors are seperated and put in different interfaces. WHY interface? WHY NOT abstract classes?

Also, in page 5, one of the disadvantages of inheritance is "Code is duplicated across subclasses" and other is "Runtime behavior changes are difficult" - HOW? How does the inhertance cause the "Maintenance" problem?
could you please help clarify these concerns?
thanks.
Stan James
(instanceof Sidekick)
Ranch Hand

Joined: Jan 29, 2003
Posts: 8791
Interface is a more flexible and less problematic choice than abstract class. When you can make Interface work, choose it first. I use abstract classes now & then when I can provide some useful behavior to future developers, but I make sure they are very small and focused. The classes, not the developers.

Inheritance as a bad form of coupling shows up in a lot of literature and for a long time I didn't get it. I write all the classes in my little program and I don't mind the coupling because I control all the code. But if you extend a "closed" class, one that you cannot or should not modify, you run the risk that a future change in the base class will break your extension. A good guideline is to not extend a concrete class. It can be safer to wrap the class in question than to extend it.

Alan Holub seems to exaggerate just for fun, so read him with care and an eye on your blood pressure ... his Extends Is Evil article has some debatable points, but it has some food for your head in it, too.


A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Elisabeth Robson
author
Ranch Hand

Joined: May 14, 2004
Posts: 173
    
    6
Hi Tulsi,
To help see why inheritance is less flexible consider this:

If class Duck has a flying behavior in a fly() procedure, and MallardDuck and RedheadDuck extend Duck, then they inherit fly(). Fly() is set at compile time; I cannot change at runtime how MallardDucks and RedheadDucks fly. Right? I call MallardDuck.fly()... there's really no other way to make the duck fly.

In addition, if MallardDuck and RedheadDuck actually fly in a different way from the default fly() behavior in Duck, then I have to override fly() in both MallardDuck *and* RedheadDuck. If they fly the same way (but not the same way as Duck) then I've duplicated the overriding fly behavior in two classes.

By pulling out fly() into a class of its own, FlyBehavior(), we are now free to compose a duck with a fly behavior. We can change this at runtime by setting the duck's flybehavior variable to a different class with a different implementation of fly(). That is more flexible. In addition, I can reuse the same fly behavior for both the MallardDuck and the RedheadDuck, so I don't have duplicated code.

I hope this helps to clarify a bit.

Elisabeth


Co-Author of Head First JavaScript Programming
Brian Smith
Ranch Hand

Joined: Oct 26, 2002
Posts: 232
Thanks for the reply Elisabeth,

Originally posted by Elisabeth Freeman:
In addition, if MallardDuck and RedheadDuck actually fly in a different way from the default fly() behavior in Duck, then I have to override fly() in both MallardDuck *and* RedheadDuck. If they fly the same way (but not the same way as Duck) then I've duplicated the overriding fly behavior in two classes.


but what's wrong with overriding fly() method though? aren't we overriding display() method? and why is it okay then?

Originally posted by Elisabeth Freeman:

By pulling out fly() into a class of its own, FlyBehavior(), we are now free to compose a duck with a fly behavior. We can change this at runtime by setting the duck's flybehavior variable to a different class with a different implementation of fly(). That is more flexible. In addition, I can reuse the same fly behavior for both the MallardDuck and the RedheadDuck, so I don't have duplicated code.


is there design flaws by putting fly() method in FlyBehavior ABSTRACT class instead of "interface"? are we putting fly() in FlyBehavior interface because we don't know yet its implementation? i would appreciate if you could clarify these issues. thanks.
-Tulsi
Elisabeth Robson
author
Ranch Hand

Joined: May 14, 2004
Posts: 173
    
    6
The difference in overriding display() but not overriding fly() is this: the character in the chapter realized that fly() was a method he'd be changing a lot. The purpose of this pattern is to allow flexibility in the "strategy" or algorithm of some object. He didn't need flexibility in display() (not yet anyway), but found he did with fly(). So that's why fly() is broken out as a separate class using the Strategy Pattern. Use a pattern only when it's needed!

We could easily have made FlyBehavior an abstract class, rather than an interface. Had there been common behavior that could be inherited by all FlyBehavior implementations, we would have done so. As it was, we didn't need that, so we implemented an interface simply so that all fly behaviors would have the same interface.

Elisabeth
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Tulsi Rai:
is there design flaws by putting fly() method in FlyBehavior ABSTRACT class instead of "interface"? are we putting fly() in FlyBehavior interface because we don't know yet its implementation?


As far as I can see, you don't gain anything by using an abstract class instead of an interface, but you lose the flexibility of multiple inheritance.

That's the only reason I can think of, but a strong one!


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Malli Raman
Ranch Hand

Joined: Nov 07, 2001
Posts: 312
I agree with Ilja.

HFDP suggests the basics two :

1. Code for contracts and not for implementation.
2. Separate the varying from constant behaviors.

the contract/interface can be a Java Interface or abstract class. Since Java won't support multiple inheritance it is advisable to use the interface instead of interface. In the duck class example, we already have the duck class with constant behaviors and to implement the point 1, we have to create an interface/contract for defining the flying/quacking behaviors hence required the interface.

Regards,
M.S.Raman
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: HFDP - Strategy Pattern
 
Similar Threads
SCEA description on Sun's site updated?
communicating between two web application
Each State consisting of a new Conatiner
AOP
Flex 3 : RemoteObject vs DataManagement Service