[GO] Lernen Sie das Entwurfsmuster "Abstract Factory" 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.

■ Abstrakte Fabrik

Das Abstract Factory-Muster ist eines der von GoF (Gang of Four; 4 Banden) definierten Entwurfsmuster. Der Zweck besteht darin, die Wiederverwendung mehrerer Module zu optimieren, indem die APIs zum Generieren verwandter Instanzen zusammengefasst werden. Im Japanischen wird es oft als "abstrakte Fabrik" übersetzt. Wird auch als Kit-Muster bezeichnet

UML class and sequence diagram W3sDesign_Abstract_Factory_Design_Pattern_UML.jpg UML class diagram 68747470733a2f2f71696974612d696d6167652d73746f72652e73332e61702d6e6f727468656173742d312e616d617a6f6e6177732e636f6d2f302f3130333539352f62393731323034392d616664392d323330332d653539372d3031393136333530633732382e706e67.png (Das Obige wird aus Wikipedia zitiert)

■ Beispielprogramm "Abstract Factory"

Das Abstract Factory-Muster scheint ein abstraktes Produkt zu sein, indem abstrakte Teile aus ** abstract factory ** kombiniert werden. Tatsächlich möchte ich den Python-Implementierungscode von Abstract Factory ausführen, um eine Vorstellung von der ** abstrakten Factory ** zu bekommen. Das hier aufgenommene Beispielprogramm erstellt eine Sammlung von Links mit einer hierarchischen Struktur als HTML-Datei.

--Wenn Sie im ListFactory-Modus arbeiten, wird eine HTML-Datei mit Links im Listenformat generiert.

(1) Versuchen Sie, ListFactory auszuführen

Lassen Sie uns zunächst den Code ausführen, der die ** Link-basierte ** Webseite erstellt.

$ python Main.py ListFactory
[LinkPage.html] was created.

Eine Datei namens "LinkPage.html" wurde generiert. Als ich das Erscheinungsbild mit einem Webbrowser überprüfte, sah es so aus. listfactory.png

(2) Versuchen Sie, TableFactory auszuführen

Lassen Sie uns als Nächstes den Code ausführen, der eine ** tabellenbasierte ** Webseite erstellt.

$ python Main.py TableFactory
[LinkPage.html] was created.

Eine Datei namens "LinkPage.html" wurde generiert. Als ich das Erscheinungsbild mit einem Webbrowser überprüfte, sah es so aus. tablefactory.png

■ Details zum Beispielprogramm

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

--Verzeichnisaufbau

.
├── Main.py
└── factory
    ├── __init__.py
    ├── factory.py
    ├── listfactory
    │   ├── __init__.py
    │   └── list_factory.py
    └── tablefactory
        ├── __init__.py
        └── table_factory.py

(1) Die Rolle von AbstractProduct

Die Rolle "AbstractProduct" definiert die Schnittstelle der abstrakten Teile und Produkte, die durch die Rolle "AbstractFactory" erstellt wurden. Im Beispielprogramm übernehmen die Klassen "Link", "Tray" und "Page" diese Rolle.

factory/factory.py


import sys
from abc import ABCMeta, abstractmethod

... (snip)

class Item(metaclass=ABCMeta):
    def __init__(self, caption):
        self.caption = caption

    @abstractmethod
    def makeHtml(self):
        pass

class Link(Item, metaclass=ABCMeta):
    def __init__(self, caption, url):
        super().__init__(caption)
        self.url = url

class Tray(Item, metaclass=ABCMeta):
    def __init__(self, caption):
        super().__init__(caption)
        self.tray = []

    def add(self, item):
        self.tray.append(item)

class Page(metaclass=ABCMeta):
    def __init__(self, title, author):
        self.title = title
        self.author = author
        self.content = []

    def add(self, item):
        self.content.append(item)

    def output(self):
        try:
            filename = self.title + '.html'
            writer = open(filename, 'w')
            writer.write(self.makeHtml())
            writer.close()
            print("[" + filename + "]" + " was created.")
        except Exception as e:
            print(e)
            sys.exit(1)

    @abstractmethod
    def makeHtml(self):
        pass

(2) Die Rolle von AbstractFactory

Die Rolle "AbstractFactory" definiert die Schnittstelle zum Erstellen einer Instanz der Rolle "AbstractProduct". Im Beispielprogramm übernimmt die Factory-Klasse diese Rolle.

factory/factory.py


import sys
from abc import ABCMeta, abstractmethod

class Factory(metaclass=ABCMeta):
    @abstractmethod
    def createLink(self, caption, url):
        pass

    @abstractmethod
    def createTray(self, caption):
        pass

    @abstractmethod
    def createPage(self, title, author):
        pass

... (snip)

(3) Die Rolle des Kunden

Die "Client" -Rolle erledigt ihre Aufgabe nur über die Schnittstelle zwischen den Rollen "AbstractFactory" und "AbstractProduct". Die Rolle des "Kunden" kennt keine spezifischen Teile, Produkte oder Fabriken. Im Beispielprogramm übernimmt die Methode "startMain" diese Rolle.

Main.py


import sys
import inspect
import factory

def startMain(factoryObject):
    asahi = factoryObject.createLink("Asahi", "http://www.asahi.com")
    yomiuri = factoryObject.createLink("Yomiuri", "http://www.yomiuri.co.jp")
    us_yahoo = factoryObject.createLink("Yahoo", "http://www.yahoo.com")
    jp_yahoo = factoryObject.createLink("Yahoo!Japan", "http://www.yahoo.co.jp")
    google = factoryObject.createLink("Google", "http://www.google.com")
    excite = factoryObject.createLink("Excite", "http://www.excite.co.jp")

    traynews = factoryObject.createTray("Newspaper")
    traynews.add(asahi)
    traynews.add(yomiuri)

    trayyahoo = factoryObject.createTray("Yahoo!")
    trayyahoo.add(us_yahoo)
    trayyahoo.add(jp_yahoo)

    traysearch = factoryObject.createTray("Search Engine")
    traysearch.add(trayyahoo)
    traysearch.add(excite)
    traysearch.add(google)

    page = factoryObject.createPage("LinkPage", "Hiroshi Yuki")
    page.add(traynews)
    page.add(traysearch)
    page.output()

if __name__ == '__main__':
    for _, plugin in inspect.getmembers(factory, inspect.isclass):
        if plugin.__name__ == sys.argv[1]:
            startMain(plugin())

(4) Die Rolle des Betonprodukts

Die Rolle "ConcreteProduct" implementiert die Schnittstelle für die Rolle "AbstractProduct". Im Beispielprogramm übernehmen die folgenden Klassen diese Rolle:

factory/listfactory/list_factory.py


from factory.factory import Factory, Link, Tray, Page

... (snip)

class ListLink(Link):
    def __init__(self, caption, url):
        super().__init__(caption, url)

    def makeHtml(self):
        return '  <li><a href="{}">{}</a></li>\n'.format(self.url, self.caption)

class ListTray(Tray):
    def __init__(self, caption):
        super().__init__(caption)

    def makeHtml(self):
        buf = []
        buf.append('<li>\n')
        buf.append(self.caption + '\n')
        buf.append('<ul>\n')

        for item in self.tray:
            buf.append(item.makeHtml())

        buf.append('</ul>\n')
        buf.append('</li>\n')
        return ''.join(buf)

class ListPage(Page):
    def __init__(self, title, author):
        super().__init__(title, author)

    def makeHtml(self):
        buf = []
        buf.append('''
<html>
  <head><title>{}</title></head>
'''.format(self.title))
        buf.append('<body>\n')
        buf.append('<h1>{}</h1>'.format(self.title))
        buf.append('<ul>')

        for item in self.content:
            buf.append(item.makeHtml())

        buf.append('</ul>')
        buf.append('<hr><adress>{}</adress>'.format(self.author))
        buf.append('</body>\n</html>\n')
        return ''.join(buf)

factory/tablefactory/table_factory.py


from factory.factory import Factory, Link, Tray, Page

... (snip)

class TableLink(Link):
    def __init__(self, caption, url):
        super().__init__(caption, url)

    def makeHtml(self):
        return '<td><a href={}>{}</a></td>'.format(self.url, self.caption)

class TableTray(Tray):
    def __init__(self, caption):
        super().__init__(caption)

    def makeHtml(self):
        buf = []
        buf.append('<td>')
        buf.append('<table width="100%" border="1"><tr>')
        buf.append('<td bgcolor="#cccccc" algin="center" colsapn="{}"><b>{}</b></td>'.format(len(self.tray), self.caption))
        buf.append('</tr>\n')
        buf.append('<tr>\n')

        for item in self.tray:
            buf.append(item.makeHtml())

        buf.append('</tr></table>')
        buf.append('</td>')
        return ''.join(buf)

class TablePage(Page):
    def __init__(self, title, author):
        super().__init__(title, author)

    def makeHtml(self):
        buf = []
        buf.append('''
<html>
  <head><title>{}</title></head>
    '''.format(self.title))
        buf.append('<body>\n')
        buf.append('<h1>{}</h1>'.format(self.title))
        buf.append('<table width="80%" border="3">\n')

        for item in self.content:
            buf.append('<tr>{}</tr>'.format(item.makeHtml()))

        buf.append('</table>')
        buf.append('<hr><adress>{}</adress>'.format(self.author))
        buf.append('</body>\n</html>\n')
        return ''.join(buf)

(5) Die Rolle der Betonfabrik

Die Rolle "ConcreteFactory" implementiert die Schnittstelle für die Rolle "AbstractFactory". Im Beispielprogramm übernehmen die folgenden Klassen diese Rolle:

--ListFactory Klasse

factory/__init__.py


from factory.listfactory.list_factory import ListFactory
from factory.tablefactory.table_factory import TableFactory

__all__ = [
    "ListFactory",
    "TableFactory"   
]

factory/listfactory/list_factory.py


from factory.factory import Factory, Link, Tray, Page

class ListFactory(Factory):
    def createLink(self, caption, url):
        return ListLink(caption, url)

    def createTray(self, caption):
        return ListTray(caption)

    def createPage(self, title, author):
        return ListPage(title, author)

... (snip)

factory/tablefactory/table_factory.py


from factory.factory import Factory, Link, Tray, Page

class TableFactory(Factory):
    def createLink(self, caption, url):
        return TableLink(caption, url)

    def createTray(self, caption):
        return TableTray(caption)

    def createPage(self, title, author):
        return TablePage(title, author)

... (snip)

■ Referenz-URL

Recommended Posts

Lernen Sie das Entwurfsmuster "Abstract Factory" mit Python
Lernen Sie das Entwurfsmuster "Factory Method" in Python
Lernen Sie das Entwurfsmuster "Prototype" mit Python
Lernen Sie das Entwurfsmuster "Builder" mit Python
Lernen Sie das Designmuster "Flyweight" in Python
Lernen Sie das Entwurfsmuster "Observer" 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 "Bridge" 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 "Composite" mit Python
Lernen Sie das Entwurfsmuster "State" in Python
Lernen Sie das Entwurfsmuster "Adapter" mit Python
Lernen Sie das Entwurfsmuster "Vorlagenmethode" 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
[Viererbande] Designmusterlernen - Abstract Factory
Entwurfsmuster #Factory-Methode
Besuchermuster in Python
Ich habe ein Designmuster in der Kotlin Factory Edition geschrieben
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
Speichern Sie die Binärdatei in Python
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
Überprüfen Sie das Verhalten des Zerstörers 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)
GoF-Entwurfsmuster aus dem Problem 2. Struktur