Behavioral Design Patterns provide solution for the better interaction between objects and how to provide lose coupling and flexibility to extend easily. Following design patterns come under this category.
Command pattern allows you to encapsulate actions in objects. The key idea behind this pattern is to provide the means to decouple client from receiver.
In the Command pattern, a Command
interface declares a method for executing a particular action. Concrete Command
classes implement the execute()
method of the Command
interface, and this execute()
method invokes the appropriate action method of a Receiver
class that the concrete Command
class contains. The Receiver
class performs a particular action. A Client
class is responsible for creating a concrete Command
and setting the Receiver
of the concrete Command
. An Invoker
class contains a reference to a Command
and has a method to execute the Command
.
In other words, it’s used to implement lose coupling in a request-response model. In Command pattern, the request is send to the Invoker
and Invoker
passes it to the encapsulated Command
object. Command
object passes the request to the appropriate method of Receiver
to perform the specific action. The Client
program creates the Receiver
object and then attaches it to the Command
. Then it creates the Invoker
object and attaches the Command
object to perform an action. Now when client program executes the action, it’s processed based on the Command
and Receiver
object.
In the Command pattern, the Invoker
is decoupled from the action performed by the Receiver
. The Invoker
has no knowledge of the Receiver
. The Invoker
invokes a Command
, and the Command
executes the appropriate action of the Receiver
. Thus, the Invoker
can invoke commands without knowing the details of the action to be performed. In addition, this decoupling means that changes to the receiver’s action don’t directly affect the invocation of the action.
The classes participating in the pattern are:
Command
declares an interface for executing an operation.ConcreteCommand
extends the Command
interface, implementing the execute()
method by invoking the corresponding operations on Receiver
. It defines a link between the Receiver
and the action.Client
creates a ConcreteCommand
object and sets its Receiver
.Invoker
asks the Command
to carry out the request.Receiver
knows how to perform the operations;The following sequence diagram shows the relationship in a clearer way:
When to use the Command design pattern
execute()
method can memorize the state and allow going back to that state).Java
Here is an example of the Command pattern. We have a Command
interface with an execute()
method.
File Command.java.
public interface Command { public void execute(); }
LunchCommand
implements Command
. It contains a reference to Lunch
, a receiver. Its execute()
method invokes the appropriate action on the receiver.
File LunchCommand.java.
public class LunchCommand implements Command { Lunch lunch; public LunchCommand(Lunch lunch) { this.lunch = lunch; } @Override public void execute() { lunch.makeLunch(); } }
The DinnerCommand
is similar to LunchCommand
. It contains a reference to Dinner
, a receiver. Its execute()
method invokes the makeDinner()
action of the Dinner
object.
File DinnerCommand.java.
public class DinnerCommand implements Command { Dinner dinner; public DinnerCommand(Dinner dinner) { this.dinner = dinner; } @Override public void execute() { dinner.makeDinner(); } }
Lunch
is a receiver.
File Lunch.java.
public class Lunch { public void makeLunch() { System.out.println("Lunch is being made"); } }
Dinner
is also a receiver.
File Dinner.java.
public class Dinner { public void makeDinner() { System.out.println("Dinner is being made"); } }
MealInvoker
is the invoker class. It contains a reference to the Command
to invoke. Its invoke()
method calls the execute()
method of the Command
.
File MealInvoker.java.
public class MealInvoker { Command command; public MealInvoker(Command command) { this.command = command; } public void setCommand(Command command) { this.command = command; } public void invoke() { command.execute(); } }
The Demo
class demonstrates the command pattern. It instantiates a Lunch
(receiver) object and creates a LunchCommand
(concrete command) with the Lunch
. The LunchCommand
is referenced by a Command
interface reference. Next, we perform the same procedure on the Dinner
and DinnerCommand
objects. After this, we create a MealInvoker
object with lunchCommand
, and we call the invoke()
method of mealInvoker
. After this, we set mealInvoker
's command to dinnerCommand
, and once again call invoke()
on mealInvoker
.
File Demo.java.
public class Demo { public static void main(String[] args) { Lunch lunch = new Lunch(); // receiver Command lunchCommand = new LunchCommand(lunch); // concrete command Dinner dinner = new Dinner(); // receiver Command dinnerCommand = new DinnerCommand(dinner); // concrete command MealInvoker mealInvoker = new MealInvoker(lunchCommand); // invoker mealInvoker.invoke(); mealInvoker.setCommand(dinnerCommand); mealInvoker.invoke(); } }
Python 3
import abc class Command(metaclass=abc.ABCMeta): @abc.abstractmethod def execute(self): pass class LunchCommand(Command): def __init__(self, lunch): self.lunch = lunch def execute(self): self.lunch.make_lunch() class DinnerCommand(Command): def __init__(self, dinner): self.dinner = dinner def execute(self): self.dinner.make_dinner() class Lunch: def make_lunch(self): print("Lunch is being made") class Dinner: def make_dinner(self): print("Dinner is being made") class MealInvoker: def __init__(self, command): self.command = command def set_command(self, command): self.command = command def invoke(self): self.command.execute() if __name__ == '__main__': lunch = Lunch() # receiver command_lunch = LunchCommand(lunch) # concrete command dinner = Dinner() # receiver command_dinner = DinnerCommand(dinner) # concrete command meal_invoker = MealInvoker(command_lunch); # invoker meal_invoker.invoke() meal_invoker.set_command(command_dinner) meal_invoker.invoke()