Python Command
Command Pattern is a behavioral design pattern that encapsulates a request into an object, allowing you to parameterize clients with different requests. Simply put, **Command Pattern wraps operations (like opening files, saving data) into independent objects**, allowing you to handle operations like data.
### Real-life Analogy
Imagine the ordering process in a restaurant:
* **Customer** (client) doesn't need to know how the chef cooks
* **Waiter** (invoker) takes orders but doesn't cook personally
* **Order** (command object) contains specific dish information
* **Chef** (receiver) performs specific cooking operations based on the order
This clearly divided labor model is the embodiment of Command Pattern in real life.
* * *
## Why Command Pattern is Needed
### Limitations of Traditional Approach
In traditional programming, we usually directly call object methods:
## Example
class Light:
def turn_on(self):
print("Light on")
def turn_off(self):
print("Light off")
# Direct call
light = Light()
light.turn_on()
light.turn_off()
This approach has several problems:
1. **Tight coupling**: Caller needs to know the receiver's specific interface
2. **Hard to extend**: Adding new features requires modifying existing code
3. **No undo/redo support**: Cannot revert operations after execution
### Advantages of Command Pattern
!(#)
Command Pattern solves the above problems by introducing an intermediate layer (command object), providing:
* **Decoupling**: No direct dependency between caller and receiver
* **Extensibility**: Easy to add new commands
* **Undo/redo support**: Can record operation history
* **Queue support**: Commands can be queued for delayed execution
* * *
## Core Components of Command Pattern
### Basic Structure
Command Pattern includes four core roles:
| Role | Responsibility | Example |
| --- | --- | --- |
| **Command** (Command Interface) | Declares interface for executing operations | `execute()`, `undo()` |
| **ConcreteCommand** (Concrete Command) | Implements command interface, binds receiver | `LightOnCommand`, `LightOffCommand` |
| **Receiver** (Receiver) | Knows how to perform operations | `Light`, `TV` |
| **Invoker** (Invoker) | Stores and executes commands | `RemoteControl` |
* * *
## Complete Code Example
### Basic Implementation
Let's understand Command Pattern through a smart home lighting control example:
## Example
from abc import ABC, abstractmethod
from typing import List
# 1. Command Interface
class Command(ABC):
@abstractmethod
def execute(self):
pass
@abstractmethod
def undo(self):
pass
# 2. Receiver - Light Device
class Light:
def turn_on(self):
print("💡 Light turned on")
def turn_off(self):
print("💡 Light turned off")
# 3. Concrete Command - Light On Command
class LightOnCommand(Command):
def __init__ (self, light: Light):
self.light= light
def execute(self):
self.light.turn_on()
def undo(self):
self.light.turn_off()
# 4. Concrete Command - Light Off Command
class LightOffCommand(Command):
def __init__ (self, light: Light):
self.light= light
def execute(self):
self.light.turn_off()
def undo(self):
self.light.turn_on()
# 5. Invoker - Remote Control
class RemoteControl:
def __init__ (self):
self.command=None
self.history: List=[]
def set_command(self, command: Command):
self.command= command
def press_button(self):
if self.command:
self.command.execute()
self.history.append(self.command)
def press_undo(self):
if self.history:
last_command =self.history.pop()
last_command.undo()
# Client Code
if __name__ =="__main__":
# Create Device
living_room_light = Light()
# Create Commands
light_on = LightOnCommand(living_room_light)
light_off = LightOffCommand(living_room_light)
# Create Remote Control
remote = RemoteControl()
# Test Light On
print("=== Test turn on light ===")
remote.set_command(light_on)
remote.press_button()
# Test Light Off
print("n=== Test turn off light ===")
remote.set_command
YouTip