For me, the link from CKing post and the example in Wikipedia are clear enough, but I’ll try to give you a new example. As they said, Strategy Pattern is mostly a way to change the behaviour of an algorithm at runtime. Of course you can achieve this in many different ways (such as holding a value and using switch-case, but it wouldn’t be as nice as Strategy Pattern).
Let’s say you’re developing a turn-based strategy game with two kind of Units: Infantry and Tank (subclasses of Unit). Your terrain could be Plains, Railroad or Forests.
class Unit{
MovementStrategy ms;
final int baseMovement;
int x,y;
public Unit(int baseMovement){
this.baseMovement = baseMovement;
}
abstract void fire();
void moveForward(){
x = x + ms.getHexagonsToMove(baseMovement);
}
void setMovementStrategy(MovementStrategy ms){
this.ms = ms;
}
}
Any Unit subclass must implement fire() method because it’s going to be completely different for them (Tank shots heavy long-distance round and Infantry shot several short distance light bullets). In this example we use normal polymorphism/inheritance since fire() method will be really different for any unit, and it won’t change during the game.
class Infantry extends Unit{
public Infantry(){
super(2);
}
void fire(){
//whatever
}
}
class Tank extends Unit{
public Tank(){
super(5);
}
void fire(){
//whatever
}
}
Units also are able to move, and have a field baseMovement that holds the number of hexagons it can walk. We’re developing a strategy game, not a real world simulation, so we don’t care how they move, we just want to add a value to their coordinates (in my example I only use X coordinate in order to get a simpler code). If all the terrain was the same, we wouldn’t need any Strategy object… but we need to change the behaviour of move() method at runtime!
So, we implement a different MovementStrategy class for each of our kinds of Terrain, and we program our game to trigger a setMovementStrategy() to any unit that move on each hexagon. And we don’t even need to write anything else in our Unit subclasses.
interface MovementStrategy{
public int getHexagonsToMove(int base);
}
class PlainMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return base;
}
}
class RailroadMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return base*3;
}
}
class ForestMovementStrategy implements MovementStrategy{
public int getHexagonsToMove(int base){
return (int)(base/2);
}
}
Now, when any Unit move inside a Forest, we call
unit.setMovementStrategy(new ForestMovementStrategy());
And as soon it goes to a Plain, we do:
unit.setMovementStrategy(new PlainMovementStrategy());
Now we’re able to change how far away our units move depending on the Terrain, and we don’t need to rewrite in any of the subclasses.
I hope this helps you a better understanding of the difference.