Ich habe Designmuster geübt, um Code zu schreiben, der sich des Designs bewusst war. Andere Entwurfsmuster werden häufig veröffentlicht.
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.
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.
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.
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. ``
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.
Recommended Posts