聽聽聽Joe's company聽makes a duck pond simulation game, SimUDuck, The game can show a large variety of duck species swimming and making quacking sounds.
Initial Design:

But now some new functionality should be added, for example: we need some of the ducks to FLY.
First Design:
聽聽聽We add a method fly() into the Duck class. It seems worked, but something went horribly wrong because not all ducks can fly. so....
Second Design:聽Using inheritance and polymorphism
聽聽聽Always override the fly() mehtod in the subclass where needed.

聽聽聽
聽聽聽Drawbacks:聽Everytime a new duck is added, you will be forced to look at and possibly override fly() and quack(). so is there a cleaner way of having only some of the duck types fly or quack?
Third Design: Using interface!
聽聽聽
Drawbacks: It completely destroy code reuse for those behaviors.
1. Design Principles: Identify the aspects of your application that vary and separate them form what stays the same!
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 which means Encapsulate the parts that vary!
2. Design Principles: Program to an interface, not an implementation! (interface here means supertype! including interface
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽and abstract class!.. making use of the polymorphism functionality).
3. Design聽Principles:聽聽Favor composition over interface!聽
Strategy Pattern: Using Composition!

Code implement:
FlyBehavior.java

public聽interface聽FlyBehavior
{
聽聽聽public聽void聽fly();
}
FlyWithWings.java

public聽class聽FlyWithWings聽implements聽FlyBehavior
{

聽聽聽public聽void聽fly()
{
聽聽聽聽聽聽System.out.println("I'm聽flying!!");
聽聽聽}
}
FlyNoWay.java

public聽class聽FlyNoWay聽implements聽FlyBehavior
{

聽聽聽public聽void聽fly()
{
聽聽聽聽聽聽System.out.println("I聽can't聽fly");
聽聽聽}
}
Duck.java

public聽abstract聽class聽Duck
{
聽聽聽FlyBehavior聽flyBehavior;

聽聽聽public聽Duck()
{聽聽聽聽聽聽
聽聽聽}
聽聽聽
聽聽聽public聽abstract聽void聽display();
聽聽聽

聽聽聽public聽void聽performFly()
{
聽聽聽聽聽聽flyBehavior.fly();
聽聽聽}
聽聽聽

聽聽聽public聽void聽swim()
{
聽聽聽聽聽聽System.out.println("All聽ducks聽float,聽even聽decoys!");
聽聽聽}
}
MallardDuck.java

public聽class聽MallardDuck
{

聽聽聽public聽MallardDuck()
{
聽聽聽聽聽聽flyBehavior=new聽FlyWithWings();聽聽聽聽聽聽
聽聽聽}
聽聽聽

聽聽聽public聽void聽display()
{
聽聽聽聽聽聽System.out.println("I'm聽a聽real聽mallard聽duck");
聽聽聽}
}The Definition聽of Strategy Pattern:聽The聽Strategy Pattern defines a family of algorithms, encapsulates each one, and makes them intercahgeable. Strategy lets the algorithm vary indepanedtl from client聽that use it
聽
Problems:
1. It's weird to have a class that's jast a behavior: classes represent things both have state and methods. a flying behavior might have instance variables representing the attributes for the flying behavior.
2.聽Be care聽of聽Over-Design: implement your code first, then refractoring!

]]>