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

Encapsulated behavior with the strategy pattern.

The Duck class that declares two reference variables for the behavior interface types. All duck subclasses inherit these.

public abstract class Duck {
	FlyBehavior flyBehavior;
	QuackBehavior quackBehavior;

	public Duck() {
	}

	public void setFlyBehavior(FlyBehavior fb) {
		flyBehavior = fb;
	}

	public void setQuackBehavior(QuackBehavior qb) {
		quackBehavior = qb;
	}

	abstract void display();

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

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

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

The interface that all flying behavior classes implement.

public interface FlyBehavior {
	public void fly();
}

And some implementations of this interface:

public class FlyWithWings implements FlyBehavior {
	public void fly() {
		System.out.println("I'm flying!!");
	}
}
public class FlyNoWay implements FlyBehavior {
	public void fly() {
		System.out.println("I can't fly");
	}
}
public class FlyRocketPowered implements FlyBehavior {
	public void fly() {
		System.out.println("I'm flying with a rocket");
	}
}

The quack behavior interface is similar to the fly behavior interface.

public interface QuackBehavior {
	public void quack();
}

The following code snippets show two implementations of that interface:

public class Quack implements QuackBehavior {
	public void quack() {
		System.out.println("Quack");
	}
}
public class MuteQuack implements QuackBehavior {
	public void quack() {
		System.out.println("<< Silence >>");
	}
}

A subclass of Duck inherits the quackBehavior and flyBehavior instance variables. If performQuack() is called on the quackBehavior member the responsibility for the quack is delegated to the Quack behavior in the following example.

public class MallardDuck extends Duck {

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

	public void display() {
		System.out.println("I'm a real Mallard duck");
	}
}

The following main application shows that with the strategy pattern it is possible to change the behavior at runtime.

public class MiniDuckSimulator {

	public static void main(String[] args) {

		Duck mallard = new MallardDuck();
		mallard.performQuack();
		mallard.performFly();

		Duck model = new ModelDuck();
		model.performFly();
		model.setFlyBehavior(new FlyRocketPowered());
		model.performFly();

	}
}

Starting this application results in the following output.

$java MiniDuckSimulator
Quack
I’m flying!!
I can’t fly
I’m flying with a rocket

Comments