it-swarm.com.de

Ist "StringBuilder" eine Anwendung des Builder-Entwurfsmusters?

Ist das "Builder" -Muster auf die Adressierung des Anti-Musters "Teleskopkonstruktor" beschränkt, oder kann gesagt werden, dass es auch das allgemeinere Problem der komplizierten Erstellung unveränderlicher Objekte anspricht?

Die Klasse StringBuilder hat den Wort "Builder" im Namen, hat jedoch nichts mit Teleskopkonstruktoren zu tun. Sie hilft uns lediglich dabei, alle Daten zu sammeln, die wir an den Konstruktor eines unveränderlichen Objekts übergeben müssen.

Für mich scheint die Antwort ein sehr klares "Ja" zu sein, aber es scheint einige Meinungsverschiedenheiten zu diesem Thema zu geben, also hatte ich gehofft, dass jemand es vielleicht klären könnte.

Ich beantwortete diese Frage: Programmierer SE: Legitime "echte Arbeit" in einem Konstruktor? wo das OP ein (vermutlich unveränderliches) Objekt erstellen möchte, das einen komplexen Baum enthält, und die Idee des "Builders" Muster tauchte auf, und während ich es recherchierte, fand ich diese Fragen und Antworten, die zu sagen scheinen, dass der "StringBuilder" -Stil der Objekterstellung nicht eine Anwendung von ist das "Builder" -Muster aus Gründen, die mir nicht klar sind: Stackoverflow - StringBuilder und Builder-Muster . (Diejenigen, die diese Frage beantworteten, haben, soweit ich das beurteilen kann, keinen überzeugenden Punkt gemacht.)

31
Mike Nakis

Ein StringBuilder ähnelt einem Builder-Muster, hat jedoch nicht viel mit der GoF-Beschreibung dieses Entwurfsmusters zu tun. Der ursprüngliche Punkt des Entwurfsmusters war

Trennen Sie die Konstruktion eines komplexen Objekts von seiner Darstellung, damit derselbe Konstruktionsprozess unterschiedliche Darstellungen erstellen kann.

- aus Design Patterns von Gamma, Helm, Johnson, Vlissides.

(Hinweis: „komplex“ bedeutet in erster Linie „aus mehreren Teilen zusammengesetzt“, nicht unbedingt „kompliziert“ oder „schwierig“)

Die "verschiedenen Darstellungen" sind hier der Schlüssel. Z.B. unter der Annahme dieses Bauprozesses:

interface ArticleBuilder {
  void addTitle(String title);
  void addParagraph(String paragraph);
}

void createArticle(ArticeBuilder articleBuilder) {
  articleBuilder.addTitle("Is String Builder an application of ...");
  articleBuilder.addParagraph("Is the Builder Pattern restricted...");
  articleBuilder.addParagraph("The StringBuilder class ...");
}

je nachdem, welche konkrete Implementierung bereitgestellt wird, erhalten wir möglicherweise ein HtmlDocument oder ein TexDocument oder ein MarkdownDocument:

class HtmlDocumentBuilder implements ArticleBuilder {
  ...
  HtmlDocument getResult();
}

HtmlDocumentBuilder b = new HtmlDocumentBuilder();
createArticle(b);
HtmlDocument dom = b.getResult();

Ein zentraler Punkt des Builder-Musters ist also der Polymorphismus . Das Buch Design Patterns vergleicht dieses Muster mit der Abstract Factory:

Abstract Factory ähnelt dem Builder darin, dass es auch komplexe Objekte erstellen kann. Der Hauptunterschied besteht darin, dass sich das Builder-Muster darauf konzentriert, Schritt für Schritt ein komplexes Objekt zu erstellen. […] Builder gibt das Produkt als letzten Schritt zurück, aber was die Abstract Factory betrifft, wird das Produkt sofort zurückgegeben.

- aus Design Patterns von Gamma, Helm, Johnson, Vlissides.

Dieser Schritt-für-Schritt-Aspekt ist dann zum populäreren Aspekt des Builder-Musters geworden, so dass das Builder-Muster im allgemeinen Sprachgebrauch folgendermaßen verstanden wird:

Teilen Sie die Konstruktion eines Objekts in mehrere Schritte auf. Dies ermöglicht es uns, benannte Argumente oder optionale Parameter auch in Sprachen zu verwenden, die diese Funktionen nicht unterstützen.

Wikipedia definiert das Muster folgendermaßen:

Das Builder-Muster ist ein Entwurfsmuster für eine Objekterstellungssoftware. Im Gegensatz zum abstrakten Fabrikmuster und dem Fabrikmethodenmuster, dessen Absicht darin besteht, Polymorphismus zu ermöglichen, besteht die Absicht des Builder-Musters darin, eine Lösung für das Anti-Muster des Teleskopkonstruktors zu finden[Zitat benötigt]. […]

Das Builder-Muster hat einen weiteren Vorteil. Es kann für Objekte verwendet werden, die flache Daten enthalten (HTML-Code, SQL-Abfrage, X.509-Zertifikat ...), dh Daten, die nicht einfach bearbeitet werden können. Diese Art von Daten kann nicht Schritt für Schritt bearbeitet werden und muss sofort bearbeitet werden. Der beste Weg, ein solches Objekt zu konstruieren, ist die Verwendung einer Builder-Klasse.[Zitat benötigt]

- von Builder-Muster auf Wikipedia , von verschiedenen Mitwirkenden.

Wie wir sehen können, gibt es kein wirklich allgemeines Verständnis dafür, auf welches Muster sich dieser Name bezieht, und in einigen Punkten widersprechen sich sogar verschiedene Definitionen (z. B. hinsichtlich der Relevanz des Polymorphismus für Builder).

Die einzige gemeinsame Eigenschaft von StringBuilder mit verschiedenen Interpretationen des Musters ist, dass das Produkt Schritt für Schritt und nicht auf einmal erstellt wird. Die GoF-Definition des Entwurfsmusters wird nicht strikt gelesen. Beachten Sie jedoch, dass Entwurfsmuster formbare Konzepte sind, die die Kommunikation erleichtern sollen. Ich würde weiterhin StringBuilder ein Beispiel für das Builder-Muster nennen, wenn auch ein atypisches - der Hauptgrund für diese Struktur in Java ist die performante Verkettung bei Vorhandensein unveränderlicher Zeichenfolgen). aber kein interessantes objektorientiertes Design.

37
amon