[GO] Lernen Sie das Entwurfsmuster "Composite" mit Python

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.

■ Composite (zusammengesetztes Muster)

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 W3sDesign_Composite_Design_Pattern_UML.jpg UML class diagram composite.png (Das Obige wird aus Wikipedia zitiert)

□ Memorandum

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 **

■ Beispielprogramm "Composite"

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

■ Details zum Beispielprogramm

Ähnlicher Code wurde in das Git-Repository hochgeladen. https://github.com/ttsubo/study_of_design_pattern/tree/master/Composite

--Verzeichnisaufbau

.
├── Main.py
└── entry.py

(1) Die Rolle des Blattes

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))

(2) Die Rolle von Composite

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)

(3) Rolle der Komponente

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())

(4) Die Rolle des Kunden

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()

(5) Andere

Fügen Sie eine Ausnahmeklasse hinzu

entry.py


class FileTreatmentException(Exception):
    def __init__(self,*args,**kwargs):
        self.message = "FileTreatmentException"

■ Referenz-URL

Recommended Posts

Lernen Sie das Entwurfsmuster "Composite" mit Python
Lernen Sie das Entwurfsmuster "Prototype" mit Python
Lernen Sie das Designmuster "Flyweight" in Python
Lernen Sie das Entwurfsmuster "Memento" mit Python
Lernen Sie das Entwurfsmuster "Proxy" in Python
Lernen Sie das Entwurfsmuster "Befehl" in Python
Lernen Sie das Entwurfsmuster "Besucher" mit Python
Lernen Sie das Entwurfsmuster "Mediator" mit Python
Lernen Sie das Designmuster "Decorator" mit Python
Lernen Sie das Entwurfsmuster "Iterator" mit Python
Lernen Sie das Entwurfsmuster "Strategie" mit Python
Lernen Sie das Entwurfsmuster "State" in Python
Lernen Sie das Entwurfsmuster "Adapter" mit Python
Lernen Sie das Entwurfsmuster "Abstract Factory" mit Python
Lernen Sie das Entwurfsmuster "Vorlagenmethode" in Python
Lernen Sie das Entwurfsmuster "Factory Method" in Python
Lernen Sie das Entwurfsmuster "Chain of Responsibility" in Python
Lernen Sie das Entwurfsmuster "Singleton" mit Python
Lernen Sie das Designmuster "Facade" mit Python
Implementieren Sie das Singleton-Muster in Python
Singleton-Muster in Python
Besuchermuster in Python
Finde Fehler in Python
Entwurfsmuster in Python: Einführung
Python Design Pattern - Template-Methode
Abrufen der arXiv-API in Python
Python im Browser: Brythons Empfehlung
Klicken Sie in Python auf die Sesami-API
Holen Sie sich den Desktop-Pfad in Python
Holen Sie sich den Skriptpfad in Python
Im Python-Befehl zeigt Python auf Python3.8
Klicken Sie auf die Web-API in Python
Ich habe die Warteschlange in Python geschrieben
Berechnen Sie den Vormonat in Python
Untersuchen Sie die Klasse eines Objekts mit Python
Holen Sie sich den Desktop-Pfad in Python
Holen Sie sich den Hostnamen in Python
Greifen Sie mit Python auf die Twitter-API zu
Der erste Schritt von Python Matplotlib
Ich habe den Stack in Python geschrieben
Beherrsche das schwache Ref-Modul in Python
Lernen Sie die Grundlagen von Python ① Grundlegende Anfänger
Laden Sie das Remote-Python-SDK mit IntelliJ
Versuchen Sie es mit der Wunderlist-API in Python
[Python Kivy] Über das Ändern des Designthemas
Versuchen Sie, die Kraken-API mit Python zu verwenden
Lernen Sie die Grundlagen, während Sie Python-Variablen berühren
Schreiben Sie den Test in die Python-Dokumentzeichenfolge
Nehmen Sie die logische Summe von List in Python (Zip-Funktion)
Zeigen Sie Python 3 im Browser mit MAMP an
Tweet mit der Twitter-API in Python
Überprüfen Sie, ob die URL in Python vorhanden ist
Ordnen Sie die in pythons models.py festgelegte Tabelle zu
Führen Sie den Python-Interpreter im Skript aus
Das Ergebnis der Installation von Python auf Anaconda
[Viererbande] Design Pattern Learning - Composite
Was ist "Mahjong" in der Python-Bibliothek? ??
Lesen Sie die Datei Zeile für Zeile mit Python