[PYTHON] Entwurfsmuster #Builder

Ich habe Designmuster geübt, um Code zu schreiben, der sich des Designs bewusst war. Andere Entwurfsmuster werden häufig veröffentlicht.

Vorwort

Das Hauptziel ist zu verstehen, wann, was und wie Entwurfsmuster verwendet werden. (Ich bin neu in Java oder einer statisch typisierten Sprache und habe keine lange Geschichte mit Python. Ich denke, es gibt einige Dinge, die Pythonista nicht ähneln. Wenn Sie Vorschläge haben, bringen Sie mir dies bitte bei.)

Diesmal der Pattern Builder zur Generierung.

Was ist Builder?

Wenn die Objekterstellungsprozedur kompliziert ist, wird der Erstellungsprozess gekapselt und eine Instanz mit einer Struktur zusammengestellt. Durch die Vorbereitung verschiedener Musterersteller ist es außerdem möglich, die Erzeugung verschiedener Muster zu handhaben, und selbst komplizierte Methodenkombinationen können gemeinsam ausgeführt werden.

Überblick

Erstellen Sie als Beispiel ein Programm, das mithilfe des Builder-Musters "Text" erstellt. Der hier erstellte Text hat die folgende Struktur.

Die Builder-Klasse definiert Methoden zum Erstellen von Dokumenten. Die Director-Klasse verwendet diese Methode dann, um ein konkretes Dokument zu erstellen.

Die Builder-Klasse ist eine abstrakte Klasse und die eigentliche Verarbeitung wird nicht geschrieben. Es werden nur abstrakte Methoden deklariert. Es ist die Unterklasse der Builder-Klasse, die die spezifische Verarbeitung zum Schreiben bestimmt.

Director kann TextBuilder zum Erstellen von Nur-Text-Dokumenten verwenden, und HTMLBuilder kann zum Erstellen von HTML-Dokumenten verwendet werden.

Gesamtklassendiagramm

builder.py


from abc import ABCMeta, abstractmethod


class Builder(metaclass=ABCMeta):

    @abstractmethod
    def make_title(self, title):
        pass

    @abstractmethod
    def make_string(self, string):
        pass

    @abstractmethod
    def make_items(self, items):
        pass

    @abstractmethod
    def close(self):
        pass

Die Builder-Klasse ist eine abstrakte Klasse, die die Methoden deklariert, mit denen "Dokumente" erstellt werden. make_title, make_string und make_items sind Methoden zum Erstellen von Titeln, Zeichenfolgen und Aufzählungszeichen in Sätzen. Die Methode close ist die Methode, mit der das Dokument vervollständigt wird.

director.py


class Director():

    def __init__(self, builder):
        self.__builder = builder

    def construct(self):
        self.__builder.make_title('Greeting')
        self.__builder.make_string('Von morgens bis mittags')
        string = ['Guten Morgen.', 'Hallo.']
        self.__builder.make_items(string)
        self.__builder.make_string('Nachts')
        string = ['Guten Abend.', 'Gute Nacht.', 'Auf Wiedersehen.']
        self.__builder.make_items(string)
        self.__builder.close()

In der Director-Klasse wird das Dokument mit den in der Builder-Klasse deklarierten Methoden erstellt.

Das Argument des Director-Klassenkonstruktors ist ein Unterklassentyp (TextBuilder-Klasse oder HTMLBuilder) der Builder-Klasse. Die Builder-Klasse ist eine abstrakte Klasse, daher können Sie keine Instanz erstellen. Der Typ der Unterklasse der angegebenen Builder-Klasse bestimmt das spezifische Dokumentformat, das von der Director-Klasse erstellt wird.

Die Konstruktmethode ist eine Methode zum Erstellen eines Dokuments. Durch Aufrufen dieser Methode wird das Dokument erstellt. Die Konstruktmethode verwendet die in Builder deklarierte Methode.

text_builder.py


from builder import Builder


class TextBuilder(Builder):
    __buffer = []

    def make_title(self, title):
        self.__buffer.append('=' * 20)
        self.__buffer.append('[' + title + ']\n')
        self.__buffer.append('\n')

    def make_string(self, string):
        self.__buffer.append('■' + string + '\n')
        self.__buffer.append('\n')

    def make_items(self, items):
        for i in range(0, len(items)):
            self.__buffer.append('●' + items[i] + '\n')
        self.__buffer.append('\n')

    def close(self):
        self.__buffer.append('=' * 20)

    def get_result(self):
        for buffer in self.__buffer:
            print(buffer)

Die TextBuilder-Klasse ist eine Unterklasse der Builder-Klasse. Erstellen Sie Ihr Dokument im Klartext. Das Ergebnis wird als String zurückgegeben.

html_builder.py


import logging
from builder import Builder


class HTMLBuilder(Builder):

    def make_title(self, title):
        self.__filename = title + '.html'

        try:
            self.__writer = open(self.__filename, mode='w')
        except IOError as e:
            logging.exception(e)

        self.__writer.write('<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>' + title + '</title></head><body>')
        self.__writer.write('<h1>' + title + '<h1>')

    def make_string(self, string):
        self.__writer.write('<h1>' + string + '</p>')

    def make_items(self, items):
        self.__writer.write('<ul>')
        for i in range(0, len(items)):
            self.__writer.write('<li>' + items[i] + '</li>')
        self.__writer.write('</ul>')

    def close(self):
        self.__writer.write('</body></html>')
        self.__writer.close()

    def get_result(self):
        return self.__filename

Die HTMLBuilder-Klasse ist auch eine Unterklasse der Builder-Klasse. Die HTMLBuilder-Klasse erstellt das Dokument als HTML-Datei. Das erstellte Ergebnis wird als Dateiname der HTML-Datei zurückgegeben.

main.py


import sys
from text_builder import TextBuilder
from html_builder import HTMLBuilder
from director import Director


def usage():
    print('Usage: Python main plain')
    print('Usage: Python main html')


def main():
    if len(sys.argv) != 2:
        usage()
        sys.exit()

    if sys.argv[1] == 'plain':
        text_builder = TextBuilder()
        director = Director(text_builder)
        director.construct()
        result = text_builder.get_result()
        print(result)
    elif sys.argv[1] == 'html':
        html_builder = HTMLBuilder()
        director = Director(html_builder)
        director.construct()
        filename = html_builder.get_result()
        print(filename + 'Wurde erschaffen.')
    else:
        usage()
        sys.exit()


if __name__ == "__main__":
    main()

Die Hauptdatei ist ein Testprogramm für das Builder-Muster. Erstellen Sie ein Dokument gemäß dem in der Befehlszeile angegebenen Format (siehe unten).

python main.py plain ・ ・ ・ Erstellen Sie ein Dokument mit einfachem Text python main.py html creation ・ ・ Dokumenterstellung mit HTML-Datei

Wenn Sie in der Befehlszeile ** plain ** angeben, übergeben Sie eine Instanz der TextBuilder-Klasse an den Director-Klassenkonstruktor. Wenn in der Befehlszeile ** html ** angegeben wird, wird eine Instanz der HTMLBuilder-Klasse an den Konstruktor der Director-Klasse übergeben.

Sowohl TextBuilder als auch HTMLBuilder sind Unterklassen von Builder, und Director verwendet nur Builder-Methoden zum Erstellen von Dokumenten. Wenn nur Builder-Methoden verwendet werden, weiß ** Director nicht, ob TextBuilder oder HTMLBuilder tatsächlich ausgeführt wird **.

Daher muss der Builder eine Reihe von Methoden deklarieren, die erforderlich und ausreichend sind, um den Zweck der Erstellung des Dokuments zu erreichen. Builder sollte jedoch keine Methoden bereitstellen, die für Nur-Text- oder HTML-Dateien spezifisch sind.

Ausführungsergebnis (normal)

====================
[Greeting]

■ Von morgens bis mittags


● Guten Morgen.

● Hallo.


■ Nachts


● Guten Abend.

● Gute Nacht.

● Auf Wiedersehen.
====================

Ausführungsergebnis (html)

`Greeting.html wurde erstellt. `` Greeting.png

Zusammenfassung

Ein Builder-Muster, das darauf spezialisiert ist, die Arbeit bei der Instanzerstellung zu reduzieren, wenn das Verfahren und der Inhalt der Instanzerstellung kompliziert sind.

In Bezug auf die Prozedur besteht der Unterschied zwischen dem Muster Vorlagenmethode und dem Builder-Muster darin, wer für die Instanziierung verantwortlich ist. Das Muster der Vorlagenmethode bestimmt die Prozedur für die Instanziierung in einer Oberklasse. Andererseits ist die Director-Klasse (andere Klasse) für die Generierungsprozedur des Builder-Musters verantwortlich.

Der Schlüssel zum Builder-Muster ist, wer weiß, wie eine Instanz erstellt wird, dh die Director-Klasse. Es ist auch wichtig, dass Benutzer von Directors wissen, was eine von Builder erstellte Instanz ist.

Es scheint, dass das Builder-Muster ins Spiel kommt, wenn es eine Prozedur zum Erstellen einer Instanz gibt, wenn Sie eine Instanz mit einer externen Ressource erstellen müssen oder wenn Sie viele verschiedene Argumente im Konstruktor haben.

Referenz

Recommended Posts

Entwurfsmuster #Builder
Entwurfsmuster #Adapter
Entwurfsmuster #Decorator
Entwurfsmuster #Observer
Entwurfsmuster #Facade
Entwurfsmuster #Strategie
Entwurfsmuster #Singleton
Entwurfsmuster #Proxy
[Viererbande] Design Pattern Learning - Builder
Entwurfsmuster #Factory-Methode
Entwurfsmuster # Template-Methode
Ich habe ein Designmuster in der Kotlin Builder Edition geschrieben
Oreore-Entwurfsmuster: Glokale Variable
Python Design Pattern - Template-Methode
[Viererbande] Designmuster lernen
Grobe Zusammenfassung des GoF-Java-Entwurfsmusters
Ich habe über Designmuster (persönliches Memo) Teil 3 (Prototypmuster, Builder-Muster) studiert.
Lernen Sie das Entwurfsmuster "Prototype" mit Python
[Viererbande] Design Pattern Learning - Singleton
[Viererbande] Design Pattern Learning --Decorator
[Viererbande] Designmuster lernen --Besucher
Design Muster-Adapter
[Viererbande] Design Pattern Learning - Vermittler
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
[Viererbande] Designmusterlernen --Iterator
GoF-Entwurfsmuster aus dem Problem 2. Struktur
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
Design Muster-Iterator
[Viererbande] Designmuster lernen - Fassade
[Viererbande] Design Pattern Learning - Composite
[Viererbande] Designmuster lernen - Prototyp
GoF-Entwurfsmuster aus dem Problem 1. Generation
Lernen Sie das Entwurfsmuster "Iterator" mit Python
[Viererbande] Designmuster lernen - Andenken
[Viererbande] Designmuster lernen - Staat
[Vierergruppe] Design Pattern Learning - Interpreter
Lernen Sie das Entwurfsmuster "Strategie" mit Python
[Viererbande] Designmuster lernen - Brücke
Lernen Sie das Entwurfsmuster "Composite" mit Python
Lernen Sie das Entwurfsmuster "Singleton" mit Python
Lernen Sie das Entwurfsmuster "State" in Python
Lernen Sie das Entwurfsmuster "Adapter" mit Python
[Viererbande] Designmuster lernen --Proxy
[Viererbande] Design Pattern Learning - Strategie
[Viererbande] Designmuster lernen --Adapter
Lernen Sie das Designmuster "Facade" mit Python
[Viererbande] Design Pattern Learning - Beobachter
[Viererbande] Designmuster lernen - Befehl
GoF-Entwurfsmuster aus dem Problem 3. Verhalten
[Viererbande] Designmuster lernen - Fluggewicht
[Viererbande] Designmusterlernen - Abstract Factory
Lernen Sie das Entwurfsmuster "Abstract Factory" mit Python
Lernen Sie das Entwurfsmuster "Vorlagenmethode" in Python
[Viererbande] Designmuster lernen - Fabrikmethode