Introduction
Command design pattern states that the client request can be encapsulated in an object called command, which is further delivered to the appropriate receiver which knows how to handle this client request.
Why is this pattern needed?
In use cases when multiple clients might need the same functionality to be shared then command design is the way to go. Where the business logic is decoupled from the clients hence the same code can be reused.
One example to make this idea concrete is save selected from the UI editor menu or Ctrl + S should essentials be saving the file. Both this type of request can be encapsulated in the command, furthermore save functionality can be invoked as receiver of the request.
Now let’s dive in for more details.
Command design pattern Internals
Command pattern broadly divided in three components
- The command object which encapsulates the request.
- The Invoker objects which creates the request that needs to be executed.
- The receiver object executes the actual request set by the client.
Now let’s take a real world analogy on how this pattern can be used in real world scenarios.
Restaurant ordering implementation
Functional requirements restaurant ordering
- Restaurants should support ordering items from the menu.
- Menu should support only limited fast food items to keep the scope limited.
- Menu has only Burger, Pizza option.
Restaurant ordering system Implement in Java
Main.java
import working.example.tech.DesignPattern.Behavioural.CommandPattern.*;
public class Main {
public static void main(String[] args) {
Waiter waiter = new Waiter();
waiter.RunTest();
}
}
FastFoodCommand.java
package working.example.tech.DesignPattern.Behavioural.CommandPattern;
public interface FastFoodCommand {
void execute();
}
BurgerCommand.java
package working.example.tech.DesignPattern.Behavioural.CommandPattern;
public class BurgerCommand implements FastFoodCommand{
Chef chef;
BurgerCommand(Chef chef) {
this.chef = chef;
}
@Override
public void execute() {
// TODO Auto-generated method stub
chef.makeBurger();
}
}
PizzaCommand.java
package working.example.tech.DesignPattern.Behavioural.CommandPattern;
public class PizzaCommand implements FastFoodCommand {
Chef chef;
PizzaCommand(Chef chef) {
this.chef = chef;
}
@Override
public void execute() {
// TODO Auto-generated method stub
chef.makePizza();
}
}
Chef.java
package working.example.tech.DesignPattern.Behavioural.CommandPattern;
public class Chef {
public void makePizza() {
System.out.println(" Preparing pizza!!!");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println(" Here is your hot and crispy pizza!!!");
}
public void makeBurger() {
System.out.println(" Preparing Burger!!!");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println(e.toString());
}
System.out.println(" Here is your Burger!!!");
}
}
Waiter.java
package working.example.tech.DesignPattern.Behavioural.CommandPattern;
import java.util.ArrayList;
import java.util.List;
import working.example.tech.interfaces.TestCaseRunner;
public class Waiter implements TestCaseRunner{
private List<FastFoodCommand> orders;
public Waiter() {
orders = new ArrayList<FastFoodCommand>();
}
public void addOrderForCurrentCustomer(FastFoodCommand order) {
orders.add(order);
}
public void provideOrderToKitchen() {
for (FastFoodCommand order : orders) {
order.execute();
}
}
@Override
public void RunTest() {
// TODO Auto-generated method stub
Chef chef = new Chef();
System.out.println(" What would you like to have Sir .... \n [1] Burger \n [2] Pizza");
System.out.println(" I will have One Medium size pizza!! ");
PizzaCommand pizzaOrder = new PizzaCommand(chef);
this.addOrderForCurrentCustomer(pizzaOrder);
System.out.println(" And One Large Burger !!! ");
BurgerCommand burgerOrder = new BurgerCommand(chef);
this.addOrderForCurrentCustomer(burgerOrder);
System.out.println(" Okay Sir bringing It right aways, 10 mins to wait!!! ");
this.provideOrderToKitchen();
}
@Override
public void showOut() {
// TODO Auto-generated method stub
}
}
Output
What would you like to have Sir ....
[1] Burger
[2] Pizza
I will have One Medium size pizza!!
And One Large Burger !!!
Okay Sir bringing It right aways, 10 mins to wait!!!
Preparing pizza!!!
Here is your hot and crispy pizza!!!
Preparing Burger!!!
Here is your Burger!!!
Conclusion
In this blog we covered command design pattern, where the invoker and the receiver are decoupled by command object which encapsulates the request. Stay tuned for more patterns.