Als Material zum Erlernen von GoF-Entwurfsmustern scheint das Buch "Einführung in Entwurfsmuster, die in der erweiterten und überarbeiteten Java-Sprache gelernt wurden" hilfreich zu sein. Da die aufgeführten Beispiele jedoch auf JAVA basieren, habe ich dieselbe Vorgehensweise mit Python versucht, um mein Verständnis zu vertiefen.
Das zusammengesetzte Muster (zusammengesetztes Muster) ist eines der von GoF (Gang of Four; 4 Banden) definierten Entwurfsmuster. Es gehört zu "Strukturmuster". Das zusammengesetzte Muster kann verwendet werden, um rekursive Datenstrukturen mit Baumstrukturen wie Verzeichnissen und Dateien darzustellen. Die Objekte, die im zusammengesetzten Muster angezeigt werden, sind "Zweige" und "Blätter", die eine gemeinsame Schnittstelle implementieren. Daher besteht der Vorteil, dass Zweige und Blätter auf die gleiche Weise behandelt werden können.
UML class and object diagram UML class diagram (Das Obige wird aus Wikipedia zitiert)
Dies ist ein Zitat aus dem Buch "Einführung in in der Java-Sprache gelernte Entwurfsmuster", aber ich hatte Hunger.
Einige Verzeichnisse enthalten Dateien oder andere Verzeichnisse (Unterverzeichnisse). Und wieder kann dieses Unterverzeichnis andere Dateien und Unterverzeichnisse enthalten. Das Verzeichnis erstellt eine solche "verschachtelte" Struktur, eine rekursive Struktur. ... (snip) Das zusammengesetzte Muster dient zum Erstellen einer solchen Struktur, ** zum Gleichsetzen des Containers mit dem Inhalt und zum Erstellen eines Entwurfsmusters für eine rekursive Struktur **
Eigentlich möchte ich ein Beispielprogramm ausführen, das das zusammengesetzte Muster verwendet, und das folgende Verhalten überprüfen.
$ 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
Ähnlicher Code wurde in das Git-Repository hochgeladen. https://github.com/ttsubo/study_of_design_pattern/tree/master/Composite
--Verzeichnisaufbau
.
├── Main.py
└── entry.py
Es ist eine Rolle, die den "Inhalt" darstellt. Nichts anderes kann in dieser Rolle sein. Im Beispielprogramm übernimmt die Klasse "File" diese Rolle.
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))
Es ist eine Rolle, die einen "Container" darstellt. Sie können die Rolle von "Leaf" oder die Rolle von "Composite" eingeben. Im Beispielprogramm übernimmt die Klasse "Directory" diese Rolle.
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)
Dies ist eine Rolle, um die Rolle "Blatt" mit der Rolle "Verbund" gleichzusetzen. Die Rolle "Komponente" wird als eine Superklasse realisiert, die der Rolle "Blatt" und der Rolle "Verbund" gemeinsam ist. Im Beispielprogramm übernimmt die Klasse "Entry" diese Rolle.
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())
Im Beispielprogramm übernimmt die Methode "startMain" diese Rolle.
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()
Fügen Sie eine Ausnahmeklasse hinzu
entry.py
class FileTreatmentException(Exception):
def __init__(self,*args,**kwargs):
self.message = "FileTreatmentException"
Recommended Posts