En tant que matériel d'apprentissage des modèles de conception du GoF, le livre «Introduction aux modèles de conception appris dans le langage Java augmenté et révisé» semble être utile. Cependant, comme les exemples repris sont basés sur JAVA, j'ai essayé la même pratique avec Python pour approfondir ma compréhension.
Le modèle composite (modèle composite) est l'un des modèles de conception définis par le GoF (Gang of Four; 4 gangs). Il appartient au "modèle structurel". Le modèle composite peut être utilisé pour représenter des structures de données récursives avec des arborescences, telles que des répertoires et des fichiers. Les objets qui apparaissent dans le modèle composite sont des «branches» et des «feuilles», qui implémentent une interface commune. Par conséquent, il y a un avantage que les branches et les feuilles peuvent être manipulées de la même manière.
UML class and object diagram UML class diagram (Ce qui précède est cité sur Wikipedia)
Ceci est une citation du livre "Introduction aux modèles de conception appris en langage Java", mais j'avais faim.
Certains répertoires contiennent des fichiers ou d'autres répertoires (sous-répertoires). Et encore une fois, ce sous-répertoire peut contenir d'autres fichiers et sous-répertoires. Le répertoire crée une telle structure "imbriquée", une structure récursive. ... (snip) Le modèle composite sert à créer une telle structure, ** assimilant le conteneur au contenu et créant une structure récursive **
En fait, je voudrais exécuter un exemple de programme qui utilise le modèle composite et vérifier le comportement suivant.
sous-répertoires
et fichiers
au répertoire
de l'entrée racinerépertoire
au fichier
et assurez-vous qu'il échoue$ python Main.py
Making root entries...
/root (30000)
/root/bin (30000)
/root/bin/vi (10000)
/root/bin/latex (20000)
/root/tmp (0)
/root/usr (0)
Making user entries...
/root (31500)
/root/bin (30000)
/root/bin/vi (10000)
/root/bin/latex (20000)
/root/tmp (0)
/root/usr (1500)
/root/usr/yuki (300)
/root/usr/yuki/diary.html (100)
/root/usr/yuki/Composite.java (200)
/root/usr/hanako (300)
/root/usr/hanako/memo.tex (300)
/root/usr/tomura (900)
/root/usr/tomura/game.doc (400)
/root/usr/tomura/junk.mail (500)
Occurring Exception...
FileTreatmentException
Un code similaire a été téléchargé dans le référentiel Git. https://github.com/ttsubo/study_of_design_pattern/tree/master/Composite
.
├── Main.py
└── entry.py
C'est un rôle qui représente le «contenu». Rien d'autre ne peut être dans ce rôle.
Dans l'exemple de programme, la classe File
remplit ce rôle.
entry.py
class File(Entry):
def __init__(self, name, size):
self.name = name
self.size = size
def getName(self):
return self.name
def getSize(self):
return self.size
def _printList(self, prefix=''):
print("{0}/{1}".format(prefix, self))
C'est un rôle qui représente un «conteneur». Vous pouvez entrer le rôle de «Feuille» ou le rôle de «Composite».
Dans l'exemple de programme, la classe Directory
remplit ce rôle.
entry.py
class Directory(Entry):
def __init__(self, name):
self.name = name
self.directory = []
def getName(self):
return self.name
def getSize(self):
size = 0
for d in self.directory:
size += d.getSize()
return size
def add(self, entry):
entry.path = self.name
self.directory.append(entry)
def _printList(self, prefix=''):
print(prefix + "/" + str(self))
for e in self.directory:
e._printList(prefix + '/' + self.name)
Il s'agit d'un rôle pour assimiler le rôle «Feuille» au rôle «Composite». Le rôle «Composant» est réalisé comme une superclasse commune au rôle «Feuille» et au rôle «Composite». Dans l'exemple de programme, la classe ʻEntry` remplit ce rôle.
entry.py
from abc import ABCMeta, abstractmethod
... (snip)
class Entry(metaclass=ABCMeta):
@abstractmethod
def getName(self):
pass
@abstractmethod
def getSize(self):
pass
def add(self, entry):
raise FileTreatmentException
def printList(self):
self._printList()
@abstractmethod
def _printList(self, prefix=''):
pass
def __str__(self):
return "{0} ({1})".format(self.getName(), self.getSize())
Dans l'exemple de programme, la méthode startMain
remplit ce rôle.
Main.py
from abc import ABCMeta, abstractmethod
from entry import Directory, File, FileTreatmentException
def startMain():
try:
print("Making root entries...")
rootdir = Directory("root")
bindir = Directory("bin")
tmpdir = Directory("tmp")
usrdir = Directory("usr")
rootdir.add(bindir)
rootdir.add(tmpdir)
rootdir.add(usrdir)
bindir.add(File("vi", 10000))
bindir.add(File("latex", 20000))
rootdir.printList()
print("")
print("Making user entries...")
yuki = Directory("yuki")
hanako = Directory("hanako")
tomura = Directory("tomura")
usrdir.add(yuki)
usrdir.add(hanako)
usrdir.add(tomura)
yuki.add(File("diary.html", 100))
yuki.add(File("Composite.java", 200))
hanako.add(File("memo.tex", 300))
tomura.add(File("game.doc", 400))
tomura.add(File("junk.mail", 500))
rootdir.printList()
print("")
print("Occurring Exception...")
tmpfile = File("tmp.txt", 100)
bindir = Directory("bin")
tmpfile.add(bindir)
except FileTreatmentException as ex:
print(ex.message)
if __name__ == '__main__':
startMain()
Ajouter une classe d'exception
entry.py
class FileTreatmentException(Exception):
def __init__(self,*args,**kwargs):
self.message = "FileTreatmentException"
Recommended Posts