Command pattern

Command pattern

software_development

The command pattern is used to encapsulate an action in order to execute it in a second time and can be used also to create action queues and implement undo operations.

The player movement buffer

A very common example could be the movement of the player in a videogame. Every time a directional button is pressed then a movement command is inserted into the movement buffer.


public class PlayerControl{
	private List movementBuffer;

	public void addMovementCommand(MovementCommand command){
		movementBuffer.add(command);
	}
}

public interface MovementCommand{
	public void execute();
}

public class UpMovementCommand implements MovementCommand{
	private Player player;

	public void execute(){
		player.y += 1;
	}
}

public class RightMovementCommand implements MovementCommand{
	private Player player;

	public void execute(){
		player.x += 1;
	}
}

The MovementCommand interface allows us to put in the buffer different kind of movement commands that will be executed with the execute method. But how the PlayerControl executes the commands? We need to add a method that do that.


public class PlayerControl{
[...]

public void executeNextCommand(){
		MovementCommand command = movementBuffer.first();
		command.execute();
		movementBuffer.remove(command);
	}
}

When the next command has to be executed, the first item of the buffer is taken out from the list and executed, so we are sure that the commands are executed sequentially. The last thing to implement is the undo functionality. We add to the MovementCommand interface an undo method and we implement it on the classes that implement the interface.


public interface MovementCommand{
	public void execute();
	public void undo();
}

public class UpMovementCommand implements MovementCommand{
	[...]

	public void undo(){
		player.y -= 1;	
	}
}

public class RightMovementCommand implements MovementCommand{
[...]

	public void undo(){
		player.x -= 1;	
	}
}

Every command knows how to undo itself, so we need only to execute the undo method. Let’s add the missing logic to the PlayerControl.


public class PlayerControl{
	private List movementBuffer;
	private Stack executedMovementsBuffer;

	public void addMovementCommand(MovementCommand command){
		movementBuffer.add(command);
	}

	public void executeNextCommand(){
		MovementCommand command = movementBuffer.first();
		command.execute();
		movementBuffer.remove(command);
		executedMovementsBuffer.push(command);
	}

	public void undoLastCommand(){
		MovementCommand command = executedMovementsBuffer.pop();
		command.undo();
	}
}

The executedMovementsBuffer is a Stack that is populated every time a MovementCommand is executed in the executeNextCommand method. When we have to undo an action, the first element of the stack is taken out and its undo method is called.

Related News