Command Pattern

Last Updated on September 24, 2023 by KnownSense

The Command Pattern, alternatively referred to as the Action or Transaction pattern, belongs to the category of behavioral design patterns. It involves the conversion of a request into an independent object that encapsulates all relevant information about the request. This transformation enables the passing of requests as method arguments, facilitates the postponement or queuing of request execution, and provides support for operations that can be undone.

A real industrial example of the Command Pattern is a restaurant ordering system. In this scenario, the Command Pattern helps manage customer orders and kitchen operations efficiently.

Benefit

  1. Decoupling: It decouples the sender (client) of a request from the receiver (object that performs the action). This separation promotes a more modular and maintainable codebase.
  2. Flexibility: It allows for the dynamic composition of commands and operations, making it easy to add, modify, or extend functionality without affecting other parts of the system.
  3. Queueing and Undo/Redo: Commands can be easily queued and executed in a specific order, enabling features like batch processing and undo/redo functionality.
  4. Support for Logging and Auditing: Commands can be logged or audited for tracking and debugging purposes, enhancing system observability.
  5. Remote Control: It facilitates the implementation of remote control and macro recording/playback systems, where commands can be serialized and sent over a network.
  6. Transaction Management: It can be used to manage transactions in database systems, ensuring that a series of related operations either all succeed or all fail.
  7. Collaboration and Composite Patterns: It can be combined with other patterns like the Composite Pattern to build complex structures of commands, allowing for more advanced behaviors.
  8. Testing: It simplifies unit testing as you can test individual commands independently of the invoker and receiver.
  9. Separation of Concerns: It helps in separating the concerns of what needs to be done (the command) from how it’s done (the receiver).
  10. Documentation and Self-Explanatory Code: Commands are self-contained and can be named descriptively, making the code more understandable and self-documenting.

UML of Command Pattern

Implementation

Here’s a simplified example of the Command Pattern for a restaurant ordering system.

Step1: Create a class Chef who is the receiver, responsible for preparing the food.

class Chef {
    void prepareBurger() {
        System.out.println("Chef is preparing a burger.");
    }

    void prepareFries() {
        System.out.println("Chef is preparing fries.");
    }

    void prepareSoda() {
        System.out.println("Chef is pouring a soda.");
    }
}

Step2: Create the command interface.

interface Order {
    void execute();
}

Step3: Create e concrete command classes representing specific food orders.

class BurgerOrder implements Order {
    private Chef chef;

    public BurgerOrder(Chef chef) {
        this.chef = chef;
    }

    @Override
    public void execute() {
        chef.prepareBurger();
    }
}
class FriesOrder implements Order {
    private Chef chef;

    public FriesOrder(Chef chef) {
        this.chef = chef;
    }

    @Override
    public void execute() {
        chef.prepareFries();
    }
}
class SodaOrder implements Order {
    private Chef chef;

    public SodaOrder(Chef chef) {
        this.chef = chef;
    }

    @Override
    public void execute() {
        chef.prepareSoda();
    }
}

Step4: Create class Waiter acts as the invoker, taking orders and submitting them to the kitchen.

class Waiter {
    private List<Order> orders = new ArrayList<>();

    void takeOrder(Order order) {
        orders.add(order);
    }

    void placeOrders() {
        for (Order order : orders) {
            order.execute();
        }
        orders.clear();
    }
}

Step5: In main class use the waiter and order class and place the order.

public class RestaurantOrderSystem {
    public static void main(String[] args) {
        Chef chef = new Chef();
        Waiter waiter = new Waiter();

        // Customer places orders
        Order order1 = new BurgerOrder(chef);
        Order order2 = new FriesOrder(chef);
        Order order3 = new SodaOrder(chef);

        waiter.takeOrder(order1);
        waiter.takeOrder(order2);
        waiter.takeOrder(order3);

       // Waiter submits orders to the kitchen
        waiter.placeOrders();
    }
}

OUTPUT:

Chef is preparing a burger.
Chef is preparing fries.
Chef is pouring a soda.

Conclusion

In conclusion, the Command Pattern is a behavioral design pattern that encapsulates requests as objects, enabling the decoupling of senders (clients) and receivers (objects that perform actions). It allows for the queuing, delaying, or undoing of requests, providing flexibility and extensibility in managing actions in a software system. This pattern is particularly useful when you need to support various types of commands, queueing, or implementing undo/redo functionality.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to Top