Strategy Pattern ( Design Pattern )

I was reading Head First Design pattern. On first chapter, i learn Strategy pattern. Stategy pattern allows programmer to make many Objects with different methods which is encapsulated within interface in flexible way. Below an example case from Head First Design Pattern.

The programmer is asked to make Duck game simulation. The game show variety of ducks which is able to swim and make quack sound . Initial system designer creates standard OO technique by using one Duck superclass, and other specific Duck will inherits. Then, there is new requirement that the duck needs to fly above. Then it come solution again from the programmer to add new method called fly within the program. But the problem is, not all ducks can fly. So that, solution will not work. Not only that, but also not all ducks quack cause some of them squeak and mute. In order to solve that kind of problem, based on Design Pattern principal : “Identify the aspect of your application that vary and separate them from what stays the same.” Is by encapsulating vary things. The way to do that is by making interface flyable and quack in order to be implemented on required specific classes.

Class Diagram Solution :

Implementation

Duck superclass


package zisal.com.simuduck.top;

import zisal.com.simuduck.api.FlyBehavior;
import zisal.com.simuduck.api.QuackBehavior;

public abstract class Duck {

FlyBehavior flyBehavior;
QuackBehavior quackBehavior;

public abstract void display();

public void swim(){
System.out.println( "The duck can swim" );
}

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

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

FlyBehavior Interface


package zisal.com.simuduck.api;

public interface FlyBehavior {

public void fly();

}

QuackBehavior interface


package zisal.com.simuduck.api;

public interface QuackBehavior {

public void quack();

}

FlyNoWay implements FlyBehavior


package zisal.com.simuduck.api.impl;

import zisal.com.simuduck.api.FlyBehavior;

public class FlyNoWay implements FlyBehavior{
@Override
public void fly() {
System.out.println( "The duck can't fly" );
}
}

FlyWithWings implementation of FlyBehavior


package zisal.com.simuduck.api.impl;

import zisal.com.simuduck.api.FlyBehavior;

public class FlyWithWings implements FlyBehavior{

@Override
public void fly() {
System.out.println( "The duck can fly" );
}

}

MuteQuack implemetation of QuackBehavior


package zisal.com.simuduck.api.impl;

import zisal.com.simuduck.api.QuackBehavior;

public class MuteQuack implements QuackBehavior{

@Override
public void quack() {
System.out.println( "The duck is mute" );
}

}

Quack implemtation of QuackBehavior


package zisal.com.simuduck.api.impl;

import zisal.com.simuduck.api.QuackBehavior;

public class Quack implements QuackBehavior{

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

}

Squeak implementation of QuackBehavior


package zisal.com.simuduck.api.impl;

import zisal.com.simuduck.api.QuackBehavior;

public class Quack implements QuackBehavior{

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

}

Decoy Duck inherits of Duck superclass


package zisal.com.simuduck.top;

public class DecoyDuck extends Duck {

@Override
public void display() {
System.out.println( "Decoy duck" );
}

}

Mallard Duck inherits of Duck superclass


package zisal.com.simuduck.top;

import zisal.com.simuduck.api.impl.FlyWithWings;
import zisal.com.simuduck.api.impl.Quack;

public class MallardDuck extends Duck  {

public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}

@Override
public void display() {
System.out.println( "Mallard Duck" );
}

}

Red Head duck inherits of Duck behavior


package zisal.com.simuduck.top;

import zisal.com.simuduck.api.impl.FlyNoWay;
import zisal.com.simuduck.api.impl.Quack;

public class RedHeadDuck extends Duck{

public RedHeadDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyNoWay();
}

@Override
public void display() {
System.out.println( "Red Head Duck" );
}


}

Rubber Duck inherits of Duck superclass


package zisal.com.simuduck.top;

import zisal.com.simuduck.api.impl.Quack;

public class RubberDuck extends Duck{

public RubberDuck() {
quackBehavior = new Quack();
}

@Override
public void display() {
System.out.println( "Rubber Duck" );
}


}

SimUDuck Game Simulation


package zisal.com.simuduck;

import zisal.com.simuduck.top.DecoyDuck;
import zisal.com.simuduck.top.Duck;
import zisal.com.simuduck.top.MallardDuck;
import zisal.com.simuduck.top.RubberDuck;

public class DuckGame {

public static void main( String [] args ){

Duck duck = new MallardDuck();

duck.display();
duck.performFly();
duck.performQuack();
duck.swim();

duck = new RubberDuck();
duck.display();
duck.performQuack();
duck.swim();

duck = new DecoyDuck();
duck.display();
duck.swim();

}

}

Result

Class Duck as superclass has 2 method swim and display that will be implemented on all subclasses object : Mallard, Red Head, Rubber and Decoy. Flyable and quack will be implemented on each specific subclasses depends on requirement it self.

HAS A Relationship is better than IS A. means creating system using composition gives a lot more flexibility, not only encapsulate a family of algorithm into their own set of classes but also change behavior runtime. The pattern above is called STRATEGY pattern.

Tagged: , , ,

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: