The command pattern allows to represent a request as a stand-alone object. This object will encapsulate an action and parameters required for prerforming this action.
This pattern is used when:
The pattern operates with four entities:
execute() that every command should implement.This example was taken from Wikipedia and will be changed in the future.
from abc import ABCMeta, abstractmethod
class Troop:
"""
Receiver - an object representing a military detachment
"""
def move(self, direction: str) -> None:
"""
Start moving in a certain direction
"""
print('The squad started moving {}'.format(direction))
def stop(self) -> None:
"""
Stop moving
"""
print('The squad stopped moving')
class Command(metaclass=ABCMeta):
"""
Abstract base class for all commands
"""
@abstractmethod
def execute(self) -> None:
"""
Proceed to execute the command
"""
pass
@abstractmethod
def unexecute(self) -> None:
"""
Cancel command execution
"""
pass
class AttackCommand(Command):
"""
The command to conduct an attack
"""
def __init__(self, troop: Troop) -> None:
"""
Constructor.
:param troop: the squad the team is associated with
"""
self.troop = troop
def execute(self) -> None:
self.troop.move('forward')
def unexecute(self) -> None:
self.troop.stop()
class RetreatCommand(Command):
"""
The command to conduct a retreat
"""
def __init__(self, troop: Troop) -> None:
"""
Constructor.
:param troop: the squad the team is associated with
"""
self.troop = troop
def execute(self) -> None:
self.troop.move('backward')
def unexecute(self) -> None:
self.troop.stop()
class TroopInterface:
"""
Invoker - an interface through which commands can be given to a certain squad
"""
def __init__(self, attack: AttackCommand, retreat: RetreatCommand) -> None:
"""
Constructor.
:param attack: command to conduct an attack
:param retreat: command to conduct a retreat
"""
self.attack_command = attack
self.retreat_command = retreat
self.current_command = None # command that currently in progress
def attack(self) -> None:
self.current_command = self.attack_command
self.attack_command.execute()
def retreat(self) -> None:
self.current_command = self.retreat_command
self.retreat_command.execute()
def stop(self) -> None:
if self.current_command:
self.current_command.unexecute()
self.current_command = None
else:
print("Squad can't be stopped, because it is not moving')
if __name__ == '__main__':
troop = Troop()
interface = TroopInterface(AttackCommand(troop), RetreatCommand(troop))
interface.attack()
interface.stop()
interface.retreat()
interface.stop()