Command Design Pattern


Intent

It belongs to behavioral design patterns catalog.
Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.

Also Known As

Action, Transaction 

An advantage of a command pattern

  • It separates the object that invokes the operation from the object that actually performs the operation.
  • It makes easy to add new commands because existing classes remain unchanged.

Structure

Participants

1. Command
  •  declares an interface for executing an operation.
2. ConcreteCommand 
  • defines a binding between a Receiver object and an action.
  • implements Execute by invoking the corresponding operation(s) on Receiver.
3. Client
  • creates a ConcreteCommand object and sets its receiver.
4. Invoker 
  • asks the command to carry out the request.
5. Receiver 
  • knows how to perform the operations associated with carrying out a request. Any class may serve as a Receiver.

Collaborations

  • The client creates a ConcreteCommand object and specifies its receiver.
  • An Invoker object stores the ConcreteCommand object.
  • The invoker issues a request by calling Execute on the command. When commands are undoable, ConcreteCommand stores state for undoing the command prior to invoking Execute.
  • The ConcreteCommand object invokes operations on its receiver to carry out the request. 

Source code

Step 1: Create an ActionListernerCommand interface that will act as a Command.
public interface ActionListenerCommand {  
    public void execute();  
}  
Step 2: Create a Document class that will act as a Receiver.
public class Document {  
          public void open(){  
           System.out.println("Document Opened");  
       }  
       public void save(){  
           System.out.println("Document Saved");  
       }  
}  
Step 3: Create an ActionOpen class that will act as a ConcreteCommand.
public class ActionOpen implements ActionListenerCommand{  
    private Document doc;  
    public ActionOpen(Document doc) {  
        this.doc = doc;  
    }  
    @Override  
    public void execute() {  
        doc.open();  
    }  
}  
Step 4: Create an ActionSave class that will act as a ConcreteCommand.
public class ActionSave implements ActionListenerCommand{  
   private Document doc;  
   public ActionSave(Document doc) {  
        this.doc = doc;  
    }  
    @Override  
    public void execute() {  
        doc.save();  
    }  
}  
Step 5: Create a MenuOptions class that will act as an Invoker.
public class MenuOptions {
    private ActionListenerCommand openCommand;
    private ActionListenerCommand saveCommand;
 
    public MenuOptions(ActionListenerCommand open, ActionListenerCommand save) {
        this.openCommand = open;
        this.saveCommand = save;
    }
    public void clickOpen(){
       openCommand.execute();
    }
    public void clickSave(){
      saveCommand.execute();
    } 
} 
Step 6: Create a CommanPatternClient class that will act as a Client.
public class CommandPatternClient {  
    public static void main(String[] args) {  
        Document doc = new Document();  
          
        ActionListenerCommand clickOpen = new ActionOpen(doc);  
        ActionListenerCommand clickSave = new ActionSave(doc);  
          
        MenuOptions menu = new MenuOptions(clickOpen, clickSave);  
          
        menu.clickOpen();  
        menu.clickSave();  
   }  
} 
Output
Document Opened  
Document Saved  

Applicability

Use the Command pattern when you want to
  • parameterize objects by an action to perform. You can express such parameterization in a procedural language with a callback function, that is, a function that's registered somewhere to be called at a later point. Commands are an object-oriented replacement for callbacks.
  • specify, queue, and execute requests at different times. A Command object can have a lifetime independent of the original request. If the receiver of a request can be represented in an address space-independent way, then you can transfer a command object for the request to a different process and fulfill the request there,\.
  • support undo. The Command's execute operation can store state for reversing its effects in the command itself. The Command interface must have an added Unexecute operation that reverses the effects of a previous call to execute. Executed commands are stored in a history list. Unlimited-level undo and redo is achieved by traversing this list backward and forwards calling unexecute and execute, respectively.
  • support logging changes so that they can be reapplied in case of a system crash. By augmenting the Command interface with load and store operations, you can keep a persistent log of changes. Recovering from a crash involves reloading logged commands from disk and re-executing them with the execute operation.
  • structure a system around high-level operations build on primitive operations. Such a structure is common in information systems that support transactions. A transaction encapsulates a set of changes to data. The Command pattern offers a way to model transactions. Commands have a common interface, letting you invoke all transactions the same way. The pattern also makes it easy to extend the system with new transactions

Typical Use Case

  • to keep a history of requests
  • implement callback functionality
  • implement the undo functionality

Real world examples

Credits

Free Spring Boot Tutorial - 5 Hours Full Course


Watch this course on YouTube at Spring Boot Tutorial | Fee 5 Hours Full Course