Close
Restaurant deception to saw command design pattern

Command design pattern

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.
Command Pattern deception with Restaurant analogy

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.

More blogs