J'aimerais apprendre les modèles de conception GoF en Python.
Le modèle de commande (anglais: modèle de commande) est l'un des modèles de conception de la programmation orientée objet et indique un objet qui exprime une action. L'objet Command encapsule le comportement et ses paramètres associés. À titre d'exemple, supposons que la bibliothèque d'impression ait une classe PrintJob. L'utilisateur de la bibliothèque crée un nouvel objet PrintJob, définit les paramètres (document à imprimer, nombre de copies, etc.) et appelle finalement la méthode pour envoyer le travail à l'imprimante.
UML class and sequence diagram UML class diagram (Ce qui précède est cité sur Wikipedia)
En fait, je voudrais exécuter un exemple de programme qui utilise le modèle de commande et vérifier le comportement suivant.
--Créez un fichier test1.txt
avec l'autorisation de fichier" 777 "
--Créez un fichier test2.txt
avec l'autorisation de fichier" 600 "
Dans l'exemple de programme, le premier argument est le nom de fichier que vous souhaitez créer et le deuxième argument est les autorisations de fichier que vous souhaitez accorder.
$ 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
Vérifiez la liste des fichiers.
$ 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
Comme prévu, le fichier a été généré.
Un code similaire a été téléchargé dans le référentiel Git. https://github.com/ttsubo/study_of_design_pattern/tree/master/Command
.
├── Main.py
└── command
└── command.py
C'est le rôle qui détermine l'interface des instructions.
Dans l'exemple de programme, la classe Command
remplit ce rôle.
command/command.py
from abc import ABCMeta, abstractmethod
class Command(metaclass=ABCMeta):
@abstractmethod
def execute(self):
pass
@abstractmethod
def display(self):
pass
C'est le rôle qui implémente réellement l'interface pour le rôle de Command
.
Dans l'exemple de programme, les classes FileTouchCommand
et ChmodCommand
remplissent ce rôle.
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))
C'est le rôle cible lors de l'exécution de la commande du rôle ConcreteCommand
. Vous pouvez l'appeler le destinataire de la commande.
Dans l'exemple de programme, la classe FileOperator
remplit ce rôle.
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)
C'est le rôle qui démarre l'exécution de l'instruction. C'est le rôle d'appeler l'interface définie par le rôle de Command
.
Dans l'exemple de programme, la classe CompositeCommand
remplit ce rôle.
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()
C'est le rôle qui crée le rôle ConcreteCommand
et attribue le rôle Receiver à ce moment-là.
Dans l'exemple de programme, la méthode startMain
remplit ce rôle.
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))
Recommended Posts