Command Pattern
What is Command Pattern?
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations
To understand command design pattern we should understand the associated key terms like client, command, command implementation, invoker, receiver.
- Command is an interface with execute method. It is the core of contract.
- A client creates an instance of a command implementation and associates it with a receiver.
- An invoker instructs the command to perform an action.
- A Command implementation’s instance creates a binding between the receiver and an action.
- Receiver is the object that knows the actual steps to perform the action.
The following sequence diagram shows the relationship in a clearer way:
Allows the requester of a particular action to be decoupled from the object that performs the action
How to implement Command Pattern?
//Command
public interface Command
{
public void execute();
}
//Concrete Command
public class LightOnCommand
implementsCommand
{
//reference
to the light
Light light;
public LightOnCommand(Light
light)
{
this.light =
light;
}
public void execute()
{
light.switchOn();
}
}
//Concrete Command
public class LightOffCommand
implementsCommand
{
//reference
to the light
Light light;
public
LightOffCommand(Light light)
{
this.light =
light;
}
public void execute()
{
light.switchOff();
}
}
//Receiver
public class Light
{
private boolean on;
public void switchOn()
{
on = true;
}
public void switchOff()
{
on = false;
}
}
//Invoker
public class RemoteControl
{
private Command command;
public void setCommand(Command
command)
{
this.command = command;
}
public void pressButton()
{
command.execute();
}
}
//Client
public class Client
{
public static void main(String[] args)
{
RemoteControl control = new RemoteControl();
Light light = new Light();
Command lightsOn = new LightsOnCommand(light);
Command lightsOff = new LightsOffCommand(light);
//switch
on
control.setCommand(lightsOn);
control.pressButton();
//switch
off
control.setCommand(lightsOff);
control.pressButton();
}
}
Another example
public interface Command {
public abstract void execute();
}
public class OnCommand implements Command {
private ConsumerElectronics ce;
public
OnCommand(ConsumerElectronics ce) {
this.ce = ce;
}
public void execute() {
ce.on();
}
}
public class MuteAllCommand
implements Command {
List
ceList;
public MuteAllCommand(List
ceList) {
this.ceList = ceList;
}
@Override
public void execute() {
for (ConsumerElectronics
ce : ceList) {
ce.mute();
}
}
}
public interface ConsumerElectronics
{
public abstract void on();
public abstract void mute();
}
public class Television implements ConsumerElectronics
{
public void on() {
System.out.println("Television is
on!");
}
@Override
public void mute() {
System.out.println("Television is
muted!");
}
}
public class SoundSystem implements ConsumerElectronics
{
public void on() {
System.out.println("Sound system
is on!");
}
@Override
public void mute() {
System.out.println("Sound system
is muted!");
}
}
public class Button {
Command
c;
public Button(Command c) {
this.c = c;
}
public void click() {
c.execute();
}
}
public class UniversalRemote
{
public static ConsumerElectronics
getActiveDevice() {
// here we will
have a complex electronic circuit :-)
// that will
maintain current device
Television
tv = new Television();
return tv;
}
}
public class DemoCommandPattern
{
public static void main(String args[])
{
// OnCommand is
instantiated based on active device supplied by Remote
ConsumerElectronics
ce = UniversalRemote.getActiveDevice();
OnCommand
onCommand = new OnCommand(ce);
Button
onButton = new Button(onCommand);
onButton.click();
Television
tv = new Television();
SoundSystem
ss = new SoundSystem();
List
all = new ArrayList();
all.add(tv);
all.add(ss);
MuteAllCommand
muteAll = new MuteAllCommand(all);
Button
muteAllButton = new Button(muteAll);
muteAllButton.click();
}
}
- The applicability of the Command design pattern can be found in these cases below:
- parameterizes objects depending on the action they must perform
- specifies or adds in a queue and executes requests at different moments in time
- offers support for undoable actions (the Execute method can memorize the state and allow going back to that state)
- structures the system in high level operations that based on primitive operations
- decouples the object that invokes the action from the object that performs the action. Due to this usage it is also known as Producer - Consumer design pattern.
References
0 comments:
Post a Comment