Design Pattern: Strategy

 Strategy pattern defines a family of algorithms, encapsulates each one, and makes them interchangeable. It lets the algorithm vary independently from clients that use it.

Strategy Design Pattern
Strategy Design Pattern

Abstract Class: Duck.java

We create objects  after sub classing it into a concrete class from an abstract type. In our case, is the Duck Class. This provides the basis for all the XxxDuck objects that are created. Two things to be mentioned;

  1. We are programming the different “behavior” to an interface. And this could be an abstract class as well. References to these instance variables are provided as instance variables in the Class Definition.
  2. Public “Setters” are provided so that the behavior of the object can be set or changed dynamically as shown in this example.
package com.npk.strategy;

public abstract class Duck {

FlyBehavior flyBehavior;
QuackBehavior quackBehavior;

public abstract void display();

public void setFlyBehavior(FlyBehavior flyBehavior){
this.flyBehavior = flyBehavior;
}

public void setQuackBehavior(QuackBehavior quackBehavior){
this.quackBehavior = quackBehavior;
}

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

public void performQuack(){
quackBehavior.quack();
}

public void performSwim(){
System.out.println("All ducks can swim!");
}
}

Interface: FlyBehavior.java and QuackBehavior.java

Any variable behavior of an object are to be programmed to an interface.
This way, you get two things:

  1. Compostion
  2. Loosely coupled objects.

Both of which are good OO Designs aspects.


package com.npk.strategy;

public interface FlyBehavior {

public void fly();
}

package com.npk.strategy;

public interface QuackBehavior {

public void quack();
}

Concrete Implementation: DummyDuck.java

We subclass the abstract Duck class to get a concrete DummyDuck class where we can set the behavior in the class constructor ( optional )


package com.npk.strategy;

public class DummyDuck extends Duck {

public DummyDuck(){
this.setFlyBehavior(new FlyNoWay());
this.setQuackBehavior(new SquekQuack());
}

@Override
public void display() {
System.out.println("This is a dummy duck.");

}

}

Concrete classes: FlyNoWay.java and SquekQuack.java

These form the actual implementation of the FlyBehavior and the QuackBehavior interfaces respectively.


package com.npk.strategy;

public class FlyNoWay implements FlyBehavior {

@Override
public void fly() {
System.out.println("Cannot fly.");

}

}

package com.npk.strategy;

public class SquekQuack implements QuackBehavior {

@Override
public void quack() {
System.out.println("Duck squeking.");

}

}

The Application Launcher We show two things here.

  1. Setting the behavior using the constructor.
  2. Changing the set behavior using the setters provided.

package com.npk.strategy;

public class Launcher {

public static void main(String[] args) {
Duck duck = new DummyDuck();
duck.display();
duck.performFly();
duck.performQuack();

System.out.println("---------------------");
duck.setFlyBehavior(new FlyWithWings());
duck.setQuackBehavior(new MuteQuack());

duck.performFly();
duck.performQuack();
}

}

The final output


This is a dummy duck.
Cannot fly.
Duck squeking.
---------------------
Duck flying.
Mute quack.

Advertisements
Design Pattern: Strategy