I would like to learn GoF design patterns in Python.
The Command pattern (English: command pattern) is one of the design patterns in object-oriented programming, and indicates an object that expresses an action. The Command object is an encapsulation of the behavior and its associated parameters. As an example, suppose the library that prints has the PrintJob class. The library user creates a new PrintJob object, sets the parameters (document to print, number of copies, etc.), and finally calls the method to send the job to the printer.
UML class and sequence diagram UML class diagram (The above is quoted from Wikipedia)
Actually, I would like to try running a sample program that utilizes the Command pattern and check the following behavior.
--Create a test1.txt
file with file permission" 777 "
--Create a test2.txt
file with file permissions" 600 "
In the sample program, the first argument is the file name you want to create, and the second argument is the file authority you want to grant.
$ python Main.py test1.txt 777
% touch test1.txt
% chmod 777 test1.txt
$ python Main.py test2.txt 600
% touch test2.txt
% chmod 600 test2.txt
Check the file list.
$ ls -l|grep test
-rwxrwxrwx 1 ttsubo staff 0 1 26 13:01 test1.txt
-rw------- 1 ttsubo staff 0 1 26 13:01 test2.txt
As expected, the file was generated.
Similar code has been uploaded to the Git repository. https://github.com/ttsubo/study_of_design_pattern/tree/master/Command
--Directory structure
.
├── Main.py
└── command
└── command.py
It is the role that determines the interface of instructions.
In the sample program, the Command
class serves this role.
command/command.py
from abc import ABCMeta, abstractmethod
class Command(metaclass=ABCMeta):
@abstractmethod
def execute(self):
pass
@abstractmethod
def display(self):
pass
This is the role that actually implements the interface for the role of Command
.
In the sample program, the FileTouchCommand
and ChmodCommand
classes serve this role.
command/command.py
class FileTouchCommand(Command):
def __init__(self, filename, receiverObj):
self.__filename = filename
self.__receiver = receiverObj
def execute(self):
self.__receiver.createFile(self.__filename)
def display(self):
print("% touch {0}".format(self.__filename))
class ChmodCommand(Command):
def __init__(self, filename, permission, receiverObj):
self.__filename = filename
self.__permission = permission
self.__receiver = receiverObj
def execute(self):
self.__receiver.changeFileMode(self.__filename, self.__permission)
def display(self):
permission = format(self.__permission, 'o')
print("% chmod {0} {1}".format(permission, self.__filename))
This is the target role when executing the command of the ConcreteCommand
role. You may call it the recipient of the order.
In the sample program, the FileOperator
class serves this role.
command/command.py
from pathlib import Path
...(snip)
class FileOperator(object):
def createFile(self, filename):
Path(filename).touch()
def changeFileMode(self, filename, permission):
Path(filename).chmod(permission)
It is the role that starts the execution of the instruction. It serves to call the interface defined by the Command
role.
In the sample program, the CompositeCommand
class serves this role.
command/command.py
class CompositeCommand(Command):
def __init__(self):
self.__cmds = []
def append_cmd(self, cmd):
self.__cmds.append(cmd)
def execute(self):
for cmd in self.__cmds:
cmd.execute()
def display(self):
for cmd in self.__cmds:
cmd.display()
This is the role that creates the ConcreteCommand
role and assigns the Receiver role at that time.
In the sample program, the startMain
method serves this role.
Main.py
import sys
from command.command import FileOperator, CompositeCommand, FileTouchCommand, ChmodCommand
def startMain(filename, permission):
recv = FileOperator()
cc = CompositeCommand()
cc.append_cmd(FileTouchCommand(filename, recv))
cc.append_cmd(ChmodCommand(filename, permission, recv))
cc.execute()
cc.display()
if __name__ == "__main__":
startMain(sys.argv[1], int(sys.argv[2], 8))
-Implementing the Command pattern in Python -Design pattern in Python ~ Py design pattern ~ / Command pattern
Recommended Posts