Command pattern

Command Pattern is one of the Behavioural Design Patterns.

The main key of this pattern is command interface

This command interface provides abstract “execute” method.
Each concrete command class provides different implementations of execute method.

Command pattern decouples the object which invokes the operation from the one which knows how to perform it.

In this pattern, request will be encapsulated as an object which makes clients to send different requests with different parameters

We also need to understand “Sender” and “Receiver” in this pattern

Request is sent to “Sender” and “sender” pass it to the encapsulated command object

Command object passes the request to the appropriate method of Receiver to perform the specific action

Steps to implement Command pattern


1) Create the receiver interface

2) Create implementation classes for Receiver interface

3) Create a command interface with execute method

4) Create implementation classes for command interface

5) Create command invoker class which calls execute method of command

6) Create a client program to test the pattern

Let’s perform these steps with an example

Consider an example of reading and writing to files of different format like excel,pdf etc

Let’s implement this requirement with below steps


1) Create receiver interface

  1. package com.kb.command;
  2.  
  3. public interface FileReceiver {
  4.     void readFile();
  5.     void writeFile();
  6.  
  7. }
package com.kb.command;

public interface FileReceiver {
	void readFile();
	void writeFile();

}


2) Create implementation classes for Receiver interface

We will have 2 different receivers , one for PDF and other one for excel

  1. package com.kb.command;
  2.  
  3. public class PDFFileReceiver implements FileReceiver{
  4.  
  5.     @Override
  6.     public void readFile() {
  7.         System.out.println("PDF file read ... ");
  8.        
  9.     }
  10.  
  11.     @Override
  12.     public void writeFile() {
  13.         System.out.println("PDF file write ... ");
  14.        
  15.     }
  16.  
  17. }
package com.kb.command;

public class PDFFileReceiver implements FileReceiver{

	@Override
	public void readFile() {
		System.out.println("PDF file read ... ");
		
	}

	@Override
	public void writeFile() {
		System.out.println("PDF file write ... ");
		
	}

}

  1. package com.kb.command;
  2.  
  3. public class ExcelFileReceiver implements FileReceiver{
  4.  
  5.     @Override
  6.     public void readFile() {
  7.         System.out.println("Excel file read ... ");
  8.        
  9.     }
  10.  
  11.     @Override
  12.     public void writeFile() {
  13.         System.out.println("Excel file write ... ");
  14.        
  15.     }
  16.  
  17. }
package com.kb.command;

public class ExcelFileReceiver implements FileReceiver{

	@Override
	public void readFile() {
		System.out.println("Excel file read ... ");
		
	}

	@Override
	public void writeFile() {
		System.out.println("Excel file write ... ");
		
	}

}


3) Create a command interface with execute method

  1. package com.kb.command;
  2.  
  3. public interface Command {
  4.     void execute();
  5. }
package com.kb.command;

public interface Command {
	void execute();
}

4) Create implementation classes for command interface

We need to create 2 command classes one for Read operation and other one for write operation

  1. package com.kb.command;
  2.  
  3. public class ReadFileCommand implements Command{
  4.    
  5.     FileReceiver fileReceiver;
  6.    
  7.     public ReadFileCommand(FileReceiver fileReceiver) {
  8.         this.fileReceiver=fileReceiver;
  9.     }
  10.  
  11.     @Override
  12.     public void execute() {
  13.         fileReceiver.readFile();
  14.        
  15.     }
  16.  
  17. }
package com.kb.command;

public class ReadFileCommand implements Command{
	
	FileReceiver fileReceiver;
	
	public ReadFileCommand(FileReceiver fileReceiver) {
		this.fileReceiver=fileReceiver;
	}

	@Override
	public void execute() {
		fileReceiver.readFile();
		
	}

}

  1. package com.kb.command;
  2.  
  3. public class WriteFileCommand implements Command{
  4.    
  5.     FileReceiver fileReceiver;
  6.    
  7.     public WriteFileCommand(FileReceiver fileReceiver) {
  8.         this.fileReceiver=fileReceiver;
  9.     }
  10.  
  11.     @Override
  12.     public void execute() {
  13.         fileReceiver.writeFile();
  14.        
  15.     }
  16.  
  17. }
package com.kb.command;

public class WriteFileCommand implements Command{
	
	FileReceiver fileReceiver;
	
	public WriteFileCommand(FileReceiver fileReceiver) {
		this.fileReceiver=fileReceiver;
	}

	@Override
	public void execute() {
		fileReceiver.writeFile();
		
	}

}

5) Create command invoker class which calls execute method of command

  1. package com.kb.command;
  2.  
  3. public class FileCommandInvoker {
  4.    
  5. public Command command;
  6.    
  7.     public FileCommandInvoker(Command command){
  8.         this.command=command;
  9.     }
  10.    
  11.     public void execute(){
  12.         this.command.execute();
  13.     }
  14.  
  15. }
package com.kb.command;

public class FileCommandInvoker {
	
public Command command;
	
	public FileCommandInvoker(Command command){
		this.command=command;
	}
	
	public void execute(){
		this.command.execute();
	}

}

6) Create a client program to test the pattern

  1. package com.kb.command;
  2.  
  3. public class FileSystemClient {
  4.     public static void main(String[] args) {
  5.  
  6.         // Creating receiver object
  7.         FileReceiver pdfReceiver = new PDFFileReceiver();
  8.  
  9.         // creating command object and associate appropriate receiver
  10.         Command readFileCommand = new ReadFileCommand(pdfReceiver);
  11.  
  12.         // Creating invoker and associating with Command
  13.         FileCommandInvoker fileInvoker = new FileCommandInvoker(readFileCommand);
  14.  
  15.         // perform action on invoker object using execute method
  16.         fileInvoker.execute();
  17.  
  18.         // creating command object and associate appropriate receiver
  19.         Command writeFileCommand = new WriteFileCommand(pdfReceiver);
  20.  
  21.         // Creating invoker and associating with Command
  22.         fileInvoker = new FileCommandInvoker(writeFileCommand);
  23.  
  24.         // perform action on invoker object using execute method
  25.         fileInvoker.execute();
  26.  
  27.     }
  28.  
  29. }
package com.kb.command;

public class FileSystemClient {
	public static void main(String[] args) {

		// Creating receiver object
		FileReceiver pdfReceiver = new PDFFileReceiver();

		// creating command object and associate appropriate receiver
		Command readFileCommand = new ReadFileCommand(pdfReceiver);

		// Creating invoker and associating with Command
		FileCommandInvoker fileInvoker = new FileCommandInvoker(readFileCommand);

		// perform action on invoker object using execute method
		fileInvoker.execute();

		// creating command object and associate appropriate receiver
		Command writeFileCommand = new WriteFileCommand(pdfReceiver);

		// Creating invoker and associating with Command
		fileInvoker = new FileCommandInvoker(writeFileCommand);

		// perform action on invoker object using execute method
		fileInvoker.execute();

	}

}



Now we can see that both read and write commands got executed on PDFFileReceiver and hence the output is PDF file read and write operation

Similarly, If we pass ExcelFileReceiver to Commands then command will execure read and write operations of Excel file.

Important points about command pattern


Command is the main key of this pattern and we should have command interface with execute() method in it , this execute() method defines the actual contract for all the concrete commands

Receiver and command implementations kept isolated and command uses the receiver

Command implementation chooses the right receiver based on the request

We will have invoker class to pass the request from client to command

Client has to associate appropriate command to invoker and associate appropriate receiver to command

Command design pattern is easily extendible, we can add new action methods in receivers and create new Command implementations without changing the client code.

The drawback with Command design pattern is that the code gets huge and confusing with high number of action methods and because of so many associations

About the Author

Founder of javainsimpleway.com
I love Java and open source technologies and very much passionate about software development.
I like to share my knowledge with others especially on technology 🙂
I have given all the examples as simple as possible to understand for the beginners.
All the code posted on my blog is developed,compiled and tested in my development environment.
If you find any mistakes or bugs, Please drop an email to kb.knowledge.sharing@gmail.com

Connect with me on Facebook for more updates

Share this article on