Home | FAQ | Contact me

Strategy Pattern

Imagine a situation when classes differ only in their behavior. The algorithms implementing the behavior can be kept in separate classes in order for an appropriate behavior to be selected at runtime. The Strategy pattern defines an interface common to all algorithms.

What's behavior here could be something else: algorithm, approach, strategy, operation, etc.—why this is called the Strategy pattern. It could be several methods and not, just as here, a move() method.

public interface Behavior
{
  int moveCommand();
}
public class AggressiveBehavior implements Behavior
{
  public int moveCommand()
  {
    System.out.print( "  [Aggressive Behavior] if another robot found, attack him." );
    return 1;
  }
}
public class DefensiveBehavior implements Behavior
{
  public int moveCommand()
  {
    System.out.print( "  [Defensive Behavior]  if another robot found, run away." );
    return -1;
  }
}
public class NormalBehavior implements Behavior
{
  public int moveCommand()
  {
    System.out.print( "  [Normal Behavior]     if another robot found, ignore him." );
    return 0;
  }
}

Robot is the object that can exhibit any one of the defined behaviors:

public class Robot
{
  private Behavior behavior;
  private String   name;

  public Robot( String name )
  {
    this.name = name;
  }

  public void move()
  {
    int command = behavior.moveCommand();
  }

  public Behavior getBehavior() { return behavior; }
  public String   getName()     { return name; }

  public void setBehavior( Behavior behavior ) { this.behavior = behavior; }
  public void setName    ( String name )       { this.name = name; }
}
public class Main
{
  public static void main( String[] args )
  {
    System.out.println( "S t r a t e g y   P a t t e r n" );
    System.out.println( "===============================" );
    System.out.println();

    System.out.println( "Instantiate robots by name and establish their behavior:" );
    System.out.println( "---------------------------------------------------------" );
    Robot big    = new Robot( "Big Robot" );    big.setBehavior( new AggressiveBehavior() );
    Robot george = new Robot( "George v.2.1" ); george.setBehavior( new DefensiveBehavior() );
    Robot r2d2   = new Robot( "R2D2" );         r2d2.setBehavior( new NormalBehavior() );

    System.out.println( "  " + big.getName() + "    (" + big.getBehavior().getClass().getSimpleName() + ")" );
    System.out.println( "  " + george.getName() + " (" + george.getBehavior().getClass().getSimpleName() + ")" );
    System.out.println( "  " + r2d2.getName() + "         (" + r2d2.getBehavior().getClass().getSimpleName() + ")" );

    System.out.println();

    System.out.println( "Move the robots to see their behavior. Based on current position a robot" );
    System.out.println( "decides his next move. The result returned by the behavior object (robot)" );
    System.out.println( "is sent to his movement mechanism:" );
    System.out.println( "-------------------------------------------------------------------------" );
    big.move();    System.out.println( " (" + big.getName() + ")" );
    george.move(); System.out.println( "   (" + george.getName() + ")" );
    r2d2.move();   System.out.println( " (" + r2d2.getName() + ")" );

    System.out.println();
    System.out.println( "The three objects (robots) move with these behaviors:" );
    System.out.println( "-----------------------------------------------------" );
    System.out.println( "  " + big.getName() + "    is frightened." );
    System.out.println( "  " + george.getName() + " becomes angry because attacked by other robots." );
    System.out.println( "  " + r2d2.getName() + "         keeps his calm." );
    System.out.println();

    System.out.println( "Now switch two of the robots' behavior:" );
    System.out.println( "---------------------------------------" );
    big.setBehavior( new DefensiveBehavior() );
    System.out.println( "  Changed " + big.getName() + "'s behavior to " + big.getBehavior().getClass().getSimpleName() + "." );

    george.setBehavior( new AggressiveBehavior() );
    System.out.println( "  Changed " + george.getName() + "'s behavior to " + george.getBehavior().getClass().getSimpleName() + "." );
    System.out.println();

    System.out.println( "Move the robots again to see the difference:" );
    System.out.println( "--------------------------------------------" );
    big.move();    System.out.println( "   (" + big.getName() + ")" );
    george.move(); System.out.println( " (" + george.getName() + ")" );
    r2d2.move();   System.out.println( " (" + r2d2.getName() + ")" );
  }
}

Output:

S t r a t e g y   P a t t e r n
===============================

Instantiate robots by name and establish their behavior:
---------------------------------------------------------
  Big Robot    (AggressiveBehavior)
  George v.2.1 (DefensiveBehavior)
  R2D2         (NormalBehavior)

Move the robots to see their behavior. Based on current position a robot
decides his next move. The result returned by the behavior object (robot)
is sent to his movement mechanism:
-------------------------------------------------------------------------
  [Aggressive Behavior] if another robot found, attack him. (Big Robot)
  [Defensive Behavior]  if another robot found, run away.   (George v.2.1)
  [Normal Behavior]     if another robot found, ignore him. (R2D2)

The three objects (robots) move with these behaviors:
-----------------------------------------------------
  Big Robot    is frightened.
  George v.2.1 becomes angry because attacked by other robots.
  R2D2         keeps his calm.

Now switch two of change the robots' behavior:
----------------------------------------------
  Changed Big Robot's behavior to DefensiveBehavior.
  Changed George v.2.1's behavior to AggressiveBehavior.

Move the robots again to see the difference:
--------------------------------------------
  [Defensive Behavior]  if another robot found, run away.   (Big Robot)
  [Aggressive Behavior] if another robot found, attack him. (George v.2.1)
  [Normal Behavior]     if another robot found, ignore him. (R2D2)