Monday, November 10, 2008

Command Pattern

Command Pattern:

Definition:

Command pattern is an object behavioral pattern that allows us to achieve complete decoupling between sender and receiver. With this decoupling sender has no knowledge of the receiver’s interface.

Command pattern enables a client to send command without knowing about actions to be performed, those actions can later on be changed without effecting client.

The key to command pattern is the Command interface which in it’s simple form contains the execute method. Each Command class must define it’s own execute method.

Command pattern turns the request into an object, this object can be stored and passed around like other objects.

Another advantage of command pattern is to implement undo methods which actually enables us to undo the action of a command, this

Uses for the Command pattern

Command objects are useful for implementing:

Multi-level undo

If all user actions in a program are implemented as command objects, the program can keep a stack of the most recently executed commands. When the user wants to undo a command, the program simply pops the most recent command object and executes its undo() method. Note that it is not possible in all cases to undo a command.

Transactional behavior

Undo is perhaps even more essential when it's called rollback and happens automatically when an operation fails partway through. Installers need this. So do databases. Command objects can also be used to implement two-phase commit.

Networking

It is possible to send whole command objects across the network to be executed on the other machines, for example player actions in computer games.

Example to understand the concept:

Let’s go through an example of implementing command pattern to understand things quickly

  1. Define The Command Interface

package blog.sajjadparacha.commandpattern;

public interface Command {

public void execute();

}

Defines the execute method to be implemented in each command.

  1. Define The receivers

LIGHT

package blog.sajjadparacha.commandpattern;

public class Light {

public void turnLightOn(){

System.out.println("Light turned on");

}

public void turnLightOff(){

System.out.println("Light turned off");

}

}

FAN

package blog.sajjadparacha.commandpattern;

public class Fan {

public void startRoatate(){

System.out.println("Fan turned on");

}

public void stopRotate(){

System.out.println("Fan turned off");

}

}

Fan and Light here are receiver objects which actually receive a command.

  1. Define The invoker

package blog.sajjadparacha.commandpattern;

public class Switch {

Command upCommand,downCommand;

public Switch(Command up,Command down){

upCommand=up;downCommand=down;

}

public void flipUp(){

upCommand.execute();

}

public void flipDown(){

downCommand.execute();

}

}

Switch stores a command and executes it in its functions flipUp/flipDown.

  1. Define Commands

LightOnCommand

package blog.sajjadparacha.commandpatteren.commands;

import blog.sajjadparacha.commandpattern.Command;

import blog.sajjadparacha.commandpattern.Light;

public class LightOnCommand implements Command{

private Light myLight;

public LightOnCommand(Light light){

myLight=light;

}

public void execute() {

myLight.turnLightOn();

}

}

LightOffCommand

package blog.sajjadparacha.commandpatteren.commands;

import blog.sajjadparacha.commandpattern.Command;

import blog.sajjadparacha.commandpattern.Light;

public class LightOffCommand implements Command {

public void execute() {

mylight.turnLightOff();

}

private Light mylight;

public LightOffCommand(Light light){

mylight=light;

}

}

LightOnCommand and LightOffCommand are implementation of Command, They store The receiver as an instance inside them and then later on in execute method appropriate method of receiver is called.

  1. Test Command Pattern

package blog.sajjadparacha.commandpattern;

import blog.sajjadparacha.commandpatteren.commands.FanOffCommand;

import blog.sajjadparacha.commandpatteren.commands.FanOnCommand;

import blog.sajjadparacha.commandpatteren.commands.LightOffCommand;

import blog.sajjadparacha.commandpatteren.commands.LightOnCommand;

public class SwitchTest {

/**

* @param args

*/

public static void main(String[] args) {

//**Turn light on/off

Light light = new Light();

LightOnCommand lightOnCommand=new LightOnCommand(light);

LightOffCommand lightOffCommand=new LightOffCommand(light);

Switch commandSwitch = new Switch(lightOnCommand,lightOffCommand);

commandSwitch.flipUp();

commandSwitch.flipDown();

//**Start and stop fan

Fan fan = new Fan();

FanOnCommand fanOnCommand=new FanOnCommand(fan);

FanOffCommand fanOffCommand=new FanOffCommand(fan);

commandSwitch = new Switch(fanOnCommand,fanOffCommand);

commandSwitch.flipUp();

commandSwitch.flipDown();

}

}

Conclusion:

Command pattern completely decouples the object that invokes the operation (Switch) from the ones having the knowledge to perform it (Light/Fan).

The object (Client) issuing the request must only know how to issue it; it doesn’t need to know how the request will be performed.

No comments: