BP3 - Command - Learn Design Pattern From Simple Things
As an army commander, you have to plan all the tasks for the soldiers, so that they can execute them. This process is called command.
Command is a behavioral design pattern: 🖤🖤🖤🖤🤍
What is Command?
Command is a technique that object commander is used to encapsulate needed information resource, soldier to execute the task at a later time.
Why use Command?
- Its layout is easy to understand and has good extensibility when more logic comes later.
Question: I hate the Command, what are the alternatives?
Answer: Just code as normal and ignore this pattern, everything in Python is an object, so you can store any object and execute a callback easily.
When to use Command?
Question: When do I use Command?
Answer: When you have a lot of tasks, it is necessary to store and plan for them. Then (maybe after a delay) execute them as planned.
Input:
- Having resources(
Resource for the First Task,Resource for the Main Task,Resource for the Last Task), - Having tasks in order
first_task(NonSoldierCommand.execute),main_task,last_task(SoldierCommand.execute):
# nothing here
Expected Output:
- Resources are appropriately allocated to task, tasks are properly planned first, then it will be executed once the command is activated.
Commander: the first task is:
💣NonSoldierCommand.executing: (Resource for the First Task)
Commander: the main task is:
🧨Commander.executing: (Resource for the Main Task)
Commander: the last task is:
💣SoldierCommand.executing: (<class '__main__.Soldier'>, Resource for the Last Task)
Soldier.do_something with: (Resource for the Last Task)
How to implement Command?
Non-Command implementation:
def non_soldier_command_execute(payload):
print(f" 💣NonSoldierCommand.executing: ({payload})")
def soldier_command_execute(soldier, resource):
print(f" 💣SoldierCommand.executing: ({type(soldier)}, {resource})")
soldier.do_something(resource)
class Soldier:
def do_something(self, resource):
print(f" Soldier.do_something with: ({resource})")
if __name__ == "__main__":
# no planning here, just do everything at once
print("Commander: the first task is:")
non_soldier_command_execute("Resource for the First Task")
print("Commander: the main task is:")
print(f" 🧨Commander.executing: (Resource for the Main Task)")
print("Commander: the last task is:")
soldier = Soldier()
soldier_command_execute(soldier, "Resource for the Last Task")
Command Implementation:
from abc import ABC, abstractmethod
class Command(ABC):
@abstractmethod
def execute(self):
pass
class NonSoldierCommand(Command):
def __init__(self, payload):
self._payload = payload
def execute(self):
print(f" 💣NonSoldierCommand.executing: ({self._payload})")
class SoldierCommand(Command):
def __init__(self, soldier, resource):
self._soldier = soldier
self._resource = resource
def execute(self):
print(f" 💣SoldierCommand.executing: ({type(self._soldier)}, {self._resource})")
self._soldier.do_something(self._resource)
class Soldier:
def do_something(self, resource):
print(f" Soldier.do_something with: ({resource})")
class Commander:
_first_task = None
_last_task = None
def init_first_command(self, command):
self._first_task = command
def init_last_command(self, command):
self._last_task = command
def execute_main_command(self):
print("Commander: the first task is:")
if isinstance(self._first_task, Command):
self._first_task.execute()
print("Commander: the main task is:")
print(f" 🧨Commander.executing: (Resource for the Main Task)")
print("Commander: the last task is:")
if isinstance(self._last_task, Command):
self._last_task.execute()
if __name__ == "__main__":
commander = Commander()
# commander init: a command encapsulating needed information(resource) to execute the task at a later time.
non_soldier_command = NonSoldierCommand("Resource for the First Task")
commander.init_first_command(non_soldier_command)
# commander init: a command encapsulating needed information(soldier, resource) to execute the task at a later time.
soldier = Soldier()
soldier_command = SoldierCommand(soldier, "Resource for the Last Task")
commander.init_last_command(soldier_command)
# after planning, this is the later time, time to execute the tasks initiated by the commander
commander.execute_main_command()
Related posts
-
Verify vs Cert: The Python Requests Handbook
Understanding SSL/TLS in Python Requests: The 'verify' and 'cert' arguments explained with interactive animations.
-
SP7 - Proxy - Learn Design Pattern From Simple Things
The boss blocks social media so employees stay focused. That's exactly how the Proxy pattern works — controlling access between objects.
-
SP6 - Object Pool - Learn Design Pattern From Simple Things
Manufacturing planes is expensive, but raw parts are reused from a pool. That's the Object Pool pattern — reduce creation cost with smart reuse.
-
SP5 - Facade - Learn Design Pattern From Simple Things
Many departments, one entrance. The Facade pattern simplifies complex systems by exposing only what you need. Learn it from simple everyday things.