Monday, August 4, 2025

Command Design Pattern: Encapsulating Actions for Total Control

๐Ÿงพ Command Design Pattern: Encapsulating Actions for Total Control

The Command Design Pattern is a behavioral pattern that encapsulates a request as an object, thereby allowing you to parameterize clients with queues, requests, and operations. It’s especially useful for implementing undo/redo, transactional behavior, and decoupled execution.

Think of it like a remote control: each button represents a command, and pressing it triggers a specific action without needing to know how it works internally.


๐Ÿง  Core Concept

The Command Pattern turns a request into a standalone object that contains all the information needed to perform the action. This includes:

  • The method to call
  • The object that owns the method
  • Any parameters required

๐Ÿ” Key Components:

  • Command Interface: Declares the execute() method.
  • Concrete Command: Implements the command and defines the binding between a receiver and an action.
  • Receiver: Knows how to perform the operation.
  • Invoker: Stores and invokes commands.
  • Client: Configures commands and associates them with receivers.

๐Ÿงฑ Structure Overview

+---------+       +----------------+       +-------------+
| Client  |-----> | ConcreteCommand |----->|  Receiver   |
+---------+       +----------------+       +-------------+
                       ^
                       |
                 +-------------+
                 |  Command    |
                 +-------------+
                       ^
                       |
                 +-------------+
                 |  Invoker    |
                 +-------------+

๐Ÿง‘‍๐Ÿ’ป Code Example (in Python)

Let’s simulate a remote control for a light:

# Command Interface
class Command:
    def execute(self):
        raise NotImplementedError

# Receiver
class Light:
    def turn_on(self):
        print("Light is ON")

    def turn_off(self):
        print("Light is OFF")

# Concrete Commands
class LightOnCommand(Command):
    def __init__(self, light: Light):
        self.light = light

    def execute(self):
        self.light.turn_on()

class LightOffCommand(Command):
    def __init__(self, light: Light):
        self.light = light

    def execute(self):
        self.light.turn_off()

# Invoker
class RemoteControl:
    def __init__(self):
        self._commands = []

    def submit(self, command: Command):
        self._commands.append(command)
        command.execute()

# Usage
light = Light()
remote = RemoteControl()

remote.submit(LightOnCommand(light))
remote.submit(LightOffCommand(light))

✅ Benefits of Command Pattern

  • Decouples sender and receiver: The invoker doesn’t need to know the details of the action.
  • Supports undo/redo: Commands can be stored and reversed.
  • Flexible and extensible: New commands can be added without changing existing code.
  • Macro commands: Combine multiple commands into one.

๐Ÿšซ When Not to Use It

  • If the action is simple and doesn’t require encapsulation.
  • When performance is critical and command overhead is unnecessary.
  • If the system doesn’t benefit from decoupling or extensibility.

๐Ÿง  Real-World Use Cases

Use CaseExample
GUI buttonsSave, open, close actions
Undo/redo systemsText editors, drawing apps
Task schedulingJob queues, cron systems
Home automationSmart device commands
Game developmentPlayer actions, AI commands

๐Ÿ”„ Variants and Enhancements

  • Composite Commands: Group multiple commands into one.
  • Undoable Commands: Add undo() method for reversible actions.
  • Command Queues: Store and execute commands asynchronously.
  • Transactional Commands: Rollback on failure.

๐Ÿ’ฌ Final Thoughts

The Command Pattern is a powerful tool for building modular, extensible, and maintainable systems. It shines in scenarios where actions need to be queued, logged, undone, or executed later.

Whether you're designing a GUI, a game engine, or a job scheduler, the Command Pattern gives you the flexibility to manage actions with precision and clarity.

No comments:

Post a Comment

Mini RDBMS (with persistent storage) using only Python Standard Library

Mini RDBMS (with persistent storage) using only the Python Standard Library import re import json import os from typing import Any, Dict, Li...