Was ist der Unterschied zwischen dem Builder-Entwurfsmuster und dem Factory-Entwurfsmuster?
Welches ist vorteilhafter und warum?
Wie stelle ich meine Ergebnisse als Grafik dar, wenn ich diese Muster testen und vergleichen / kontrastieren möchte?
Was ist der Unterschied zwischen dem Builder-Entwurfsmuster und dem Factory-Entwurfsmuster?
Welches ist vorteilhafter und warum?
Wie stelle ich meine Ergebnisse als Grafik dar, wenn ich diese Muster testen und vergleichen / kontrastieren möchte?
Antworten:
Bei Entwurfsmustern gibt es normalerweise keine "vorteilhaftere" Lösung, die für alle Fälle funktioniert. Dies hängt davon ab, was Sie implementieren müssen.
Aus Wikipedia:
Wikipedia-Eintrag für das Factory-Design-Muster: http://en.wikipedia.org/wiki/Factory_method_pattern
Wikipedia-Eintrag für das Builder-Entwurfsmuster: http://en.wikipedia.org/wiki/Builder_pattern
quelle
Eine Factory ist einfach eine Wrapper-Funktion um einen Konstruktor (möglicherweise eine in einer anderen Klasse). Der Hauptunterschied besteht darin, dass für ein Factory-Methodenmuster das gesamte Objekt in einem einzigen Methodenaufruf erstellt werden muss, wobei alle Parameter in einer einzigen Zeile übergeben werden. Das endgültige Objekt wird zurückgegeben.
Ein Builder-Muster ist im Wesentlichen ein Wrapper-Objekt um alle möglichen Parameter, die Sie möglicherweise an einen Konstruktoraufruf übergeben möchten. Auf diese Weise können Sie Setter-Methoden verwenden, um Ihre Parameterliste langsam aufzubauen. Eine zusätzliche Methode für eine Builder-Klasse ist eine build () -Methode, die das Builder-Objekt einfach an den gewünschten Konstruktor übergibt und das Ergebnis zurückgibt.
In statischen Sprachen wie Java wird dies wichtiger, wenn Sie über mehr als eine Handvoll (möglicherweise optionaler) Parameter verfügen, da keine Teleskopkonstruktoren für alle möglichen Kombinationen von Parametern erforderlich sind. Mit einem Builder können Sie auch Setter-Methoden verwenden, um schreibgeschützte oder private Felder zu definieren, die nach dem Aufruf des Konstruktors nicht direkt geändert werden können.
Grundlegendes Fabrikbeispiel
Beispiel für einen einfachen Builder
Es kann sich lohnen, die Codebeispiele dieser beiden Wikipedia-Seiten zu vergleichen:
http://en.wikipedia.org/wiki/Factory_method_pattern
http://en.wikipedia.org/wiki/Builder_pattern
quelle
Das Factory-Muster kann fast als vereinfachte Version des Builder-Musters angesehen werden.
In der Fabrik Muster ist die Factory dafür verantwortlich, je nach Bedarf verschiedene Untertypen eines Objekts zu erstellen.
Der Benutzer einer Factory-Methode muss den genauen Subtyp dieses Objekts nicht kennen. Ein Beispiel für eine Factory-Methode
createCar
könnte aFord
oder a zurückgebenHonda
typisiertes Objekt zurückgeben.Im Builder- Muster werden auch verschiedene Untertypen von einer Builder-Methode erstellt, die Zusammensetzung der Objekte kann jedoch innerhalb derselben Unterklasse unterschiedlich sein.
Um das Auto-Beispiel fortzusetzen, haben Sie möglicherweise eine
createCar
Builder-Methode, die einHonda
Objekt vom Typ mit einem 4-Zylinder-Motor erstellt, oder aHonda
Objekt vom Typ mit 6 Zylindern erstellt. Das Builder-Muster ermöglicht diese feinere Granularität.Diagramme sowohl des Builder-Musters als auch des Factory-Methodenmusters sind auf Wikipedia verfügbar.
quelle
Das Builder-Entwurfsmuster beschreibt ein Objekt, das in mehreren Schritten ein anderes Objekt eines bestimmten Typs erstellen kann. Es enthält den erforderlichen Status für das Zielobjekt bei jedem Zwischenschritt. Überlegen Sie, was StringBuilder durchläuft, um eine endgültige Zeichenfolge zu erstellen.
Das Factory-Entwurfsmuster beschreibt ein Objekt, das in einem Schritt mehrere verschiedene, aber verwandte Objekttypen erstellen kann, wobei der spezifische Typ anhand der angegebenen Parameter ausgewählt wird. Stellen Sie sich das Serialisierungssystem vor, in dem Sie Ihren Serializer erstellen und das gewünschte Objekt in einem einzigen Ladeaufruf erstellen.
quelle
Schritt für Schritt ein komplexes Objekt erstellen: Builder-Muster
Ein einfaches Objekt wird mit einer einzigen Methode erstellt: dem Factory-Methodenmuster
Erstellen eines Objekts mithilfe mehrerer Factory-Methoden: Abstraktes Factory-Muster
quelle
Builder Pattern und Factory Pattern scheinen beide bloßen Augen ziemlich ähnlich zu sein, da sie beide Objekte für Sie erstellen.
Aber du musst genauer hinsehen
Dieses Beispiel aus dem wirklichen Leben wird den Unterschied zwischen den beiden deutlicher machen.
Angenommen, Sie ging zu einem Fast - Food - Restaurant und bestellten Essen .
1) Welches Essen?
Pizza
2) Welche Beläge?
Capsicum, Tomate, BBQ Huhn, keine Ananas
So werden verschiedene Arten von Lebensmitteln nach dem Factory-Muster hergestellt, aber die verschiedenen Varianten (Aromen) eines bestimmten Lebensmittels werden nach dem Builder-Muster hergestellt.
Pizza, Burger, Pasta
Nur Käse, Käse + Tomaten + Paprika, Käse + Tomaten usw.
Codebeispiel
Sie können die Beispielcode-Implementierung beider Muster hier sehen.
Builder Pattern
Factory Pattern
quelle
Beide sind Schöpfungsmuster, um ein Objekt zu erstellen.
1) Factory Pattern - Angenommen, Sie haben eine Superklasse und N Unterklassen. Das erstellte Objekt hängt davon ab, welcher Parameter / Wert übergeben wird.
2) Builder-Muster - um ein komplexes Objekt zu erstellen.
quelle
Zunächst einige allgemeine Dinge, die meiner Argumentation folgen sollen:
Die größte Herausforderung beim Entwurf großer Softwaresysteme besteht darin, dass sie flexibel und unkompliziert sein müssen, um Änderungen vorzunehmen. Aus diesem Grund gibt es einige Metriken wie Kopplung und Kohäsion. Um Systeme zu erhalten, deren Funktionalität leicht geändert oder erweitert werden kann, ohne dass das gesamte System von Grund auf neu entworfen werden muss, können Sie den Entwurfsprinzipien (wie SOLID usw.) folgen. Nach einer Weile erkannten einige Entwickler, dass es ähnliche Lösungen gibt, die bei ähnlichen Problemen gut funktionieren, wenn sie diesen Prinzipien folgen. Diese Standardlösungen erwiesen sich als Entwurfsmuster.
Die Entwurfsmuster sollen Sie also dabei unterstützen, die allgemeinen Entwurfsprinzipien zu befolgen, um lose gekoppelte Systeme mit hoher Kohäsion zu erzielen.
Beantwortung der Frage:
Wenn Sie nach dem Unterschied zwischen zwei Mustern fragen, müssen Sie sich fragen, welches Muster Ihr System auf welche Weise flexibler macht. Jedes Muster hat seinen eigenen Zweck, Abhängigkeiten zwischen Klassen in Ihrem System zu organisieren.
Das abstrakte Factory-Muster: GoF: „Stellen Sie eine Schnittstelle zum Erstellen von Familien verwandter oder abhängiger Objekte bereit, ohne deren konkrete Klassen anzugeben.“
Was bedeutet das? Durch die Bereitstellung einer solchen Schnittstelle wird der Aufruf des Konstruktors für jedes Produkt der Familie in der Factory-Klasse gekapselt. Und da dies der einzige Ort in Ihrem gesamten System ist, an dem diese Konstruktoren aufgerufen werden, können Sie Ihr System ändern, indem Sie eine neue Factory-Klasse implementieren. Wenn Sie die Darstellung der Fabrik durch eine andere austauschen, können Sie eine ganze Reihe von Produkten austauschen, ohne den größten Teil Ihres Codes zu berühren.
Das Builder-Muster: GoF: „Trennen Sie die Konstruktion eines komplexen Objekts von seiner Darstellung, damit derselbe Konstruktionsprozess unterschiedliche Darstellungen erstellen kann.“
Was bedeutet das ? Sie kapseln den Konstruktionsprozess in einer anderen Klasse, dem Director (GoF). Dieser Director enthält den Algorithmus zum Erstellen neuer Instanzen des Produkts (z. B. Erstellen eines komplexen Produkts aus anderen Teilen). Um die integralen Bestandteile des gesamten Produkts zu erstellen, verwendet der Director einen Builder. Durch Austauschen des Builders im Director können Sie denselben Algorithmus zum Erstellen des Produkts verwenden, jedoch die Darstellungen einzelner Teile (und damit die Darstellung des Produkts) ändern. Um Ihr System in der Darstellung des Produkts zu erweitern oder zu ändern, müssen Sie lediglich eine neue Builder-Klasse implementieren.
Kurz gesagt: Der Zweck des Abstract Factory Patterns besteht darin, eine Reihe von Produkten auszutauschen, die für die gemeinsame Verwendung hergestellt wurden. Das Builder-Muster dient dazu, den abstrakten Algorithmus zum Erstellen eines Produkts zu kapseln, um es für verschiedene Darstellungen des Produkts wiederzuverwenden.
Meiner Meinung nach kann man nicht sagen, dass das Abstract Factory Pattern der große Bruder des Builder Pattern ist. JA, beide sind Schöpfungsmuster, aber die Hauptabsicht der Muster ist völlig unterschiedlich.
quelle
Ein bemerkenswerter Unterschied zwischen Baumeister und Fabrik, den ich erkennen konnte, war der folgende
Angenommen, wir haben ein Auto
In der obigen Oberfläche können wir Auto auf folgende Weise bekommen:
aber was ist, wenn beim Erstellen der Sitze eine Ausnahme auftritt? SIE ERHALTEN DAS OBJEKT NICHT // ABER
Angenommen, Sie haben eine Implementierung wie die folgende
Jetzt können Sie so erstellen
Hier im zweiten Fall würden Sie das Auto auch dann erhalten, wenn eine Operation fehlschlägt.
Vielleicht funktioniert das Auto später nicht mehr perfekt, aber Sie hätten das Objekt.
Weil die Factory-Methode Ihnen das Auto in einem einzigen Anruf gibt, während der Builder eins nach dem anderen baut.
Obwohl es von den Bedürfnissen des Deign abhängt, für wen man sich entscheidet.
quelle
Teleskopkonstruktormuster
Analogie:
Höflichkeit
quelle
Builder und Abstract Factory haben für unterschiedliche Zwecke gedacht. Je nach richtigem Anwendungsfall müssen Sie ein geeignetes Entwurfsmuster auswählen.
Hauptmerkmale des Builders :
Fabrik (einfache Fabrik) herausragende Merkmale:
Entwürfe beginnen häufig mit der Factory-Methode (weniger kompliziert, anpassbarer, Unterklassen vermehren sich) und entwickeln sich zu Abstract Factory , Prototype oder Builder (flexibler, komplexer).
Schauen Sie sich verwandte Beiträge an:
Builder in einer separaten Klasse halten (fließende Schnittstelle)
Entwurfsmuster: Factory vs Factory-Methode vs Abstract Factory
Weitere Informationen finden Sie in den folgenden Artikeln:
Quellenherstellung
journaldev
quelle
Factory : Wird zum Erstellen einer Instanz eines Objekts verwendet, bei der die Abhängigkeiten des Objekts vollständig von der Factory gehalten werden. Für das abstrakte Fabrikmuster gibt es oft viele konkrete Implementierungen derselben abstrakten Fabrik. Die richtige Implementierung der Fabrik erfolgt über die Abhängigkeitsinjektion.
Builder : Wird zum Erstellen unveränderlicher Objekte verwendet, wenn die Abhängigkeiten des zu instanziierenden Objekts teilweise im Voraus bekannt sind und teilweise vom Client des Builders bereitgestellt werden.
quelle
Abstrakte Factory & Builder-Muster sind beide Schöpfungsmuster, jedoch mit unterschiedlicher Absicht.
Das abstrakte Fabrikmuster betont die Objekterstellung für Familien verwandter Objekte, wobei:
Das Builder-Muster konzentriert sich darauf, Schritt für Schritt ein komplexes Objekt zu erstellen. Es entkoppelt die Darstellung vom Konstruktionsprozess des komplexen Objekts, sodass derselbe Konstruktionsprozess für verschiedene Repräsentationen verwendet werden kann.
quelle
Eine komplexe Konstruktion liegt vor, wenn das zu konstruierende Objekt aus verschiedenen anderen Objekten besteht, die durch Abstraktionen dargestellt werden.
Betrachten Sie ein Menü in McDonald's. Ein Menü enthält ein Getränk, ein Hauptgericht und eine Seite. Abhängig davon, welche Nachkommen der einzelnen Abstraktionen zusammengesetzt sind, hat das erstellte Menü eine andere Darstellung.
Dort haben wir zwei Instanzen des Menüs mit unterschiedlichen Darstellungen. Der Bauprozess bleibt wiederum der gleiche. Sie erstellen ein Menü mit einem Getränk, einem Hauptgericht und einer Beilage.
Mithilfe des Builder-Musters trennen Sie den Algorithmus zum Erstellen eines komplexen Objekts von den verschiedenen Komponenten, mit denen es erstellt wurde.
In Bezug auf das Builder-Muster ist der Algorithmus im Director gekapselt, während die Builder zum Erstellen der Integralteile verwendet werden. Das Variieren des verwendeten Builders im Algorithmus des Direktors führt zu einer anderen Darstellung, da andere Teile zu einem Menü zusammengesetzt sind. Die Art und Weise, wie ein Menü erstellt wird, bleibt gleich.
quelle
Der Hauptunterschied zwischen ihnen besteht darin, dass das Builder-Muster in erster Linie die schrittweise Erstellung komplexer Objekte beschreibt. Im Muster der abstrakten Fabrik liegt der Schwerpunkt auf Familien von Objektprodukten . Builder gibt das Produkt im letzten Schritt zurück . Im Abstract Factory-Muster ist das Produkt sofort verfügbar .
Beispiel: Nehmen wir an, wir erstellen Maze
1. Abstrakte Fabrik:
2. Erbauer:
quelle
Ich glaube, die Verwendung und der Unterschied zwischen Factory & Builder-Mustern können in einem bestimmten Zeitraum leichter verstanden / geklärt werden, da Sie an derselben Codebasis gearbeitet haben und sich die Anforderungen geändert haben.
Nach meiner Erfahrung beginnen Sie normalerweise mit einem Factory-Muster, das einige statische Erstellungsmethoden enthält, um in erster Linie eine relativ komplexe Initialisierungslogik zu verbergen. Wenn Ihre Objekthierarchie komplexer wird (oder wenn Sie mehr Typen und Parameter hinzufügen), werden Ihre Methoden wahrscheinlich mit mehr Parametern gefüllt, und ganz zu schweigen davon, dass Sie Ihr Factory-Modul neu kompilieren müssen. All diese Dinge erhöhen die Komplexität Ihrer Erstellungsmethoden, verringern die Lesbarkeit und machen das Erstellungsmodul anfälliger.
Dieser Punkt ist möglicherweise der Übergangs- / Erweiterungspunkt. Auf diese Weise erstellen Sie ein Wrapper-Modul um die Konstruktionsparameter und können dann neue (ähnliche) Objekte darstellen, indem Sie (möglicherweise) weitere Abstraktionen und Implementierungen hinzufügen, ohne die tatsächliche Erstellungslogik zu berühren. Sie hatten also "weniger" komplexe Logik.
Ehrlich gesagt ist es der Unterschied, sich auf etwas zu beziehen, bei dem "ein Objekt in einem oder mehreren Schritten erstellt wird", da der einzige Diversitätsfaktor für mich nicht ausreichte, um sie zu unterscheiden, da ich in fast allen Fällen, mit denen ich konfrontiert war, beide Methoden verwenden konnte jetzt ohne irgendeinen Nutzen zu erfahren. Das ist es also, worüber ich endlich nachgedacht habe.
quelle
Der Hauptvorteil des Builder-Musters gegenüber dem Factory-Muster besteht darin, dass Sie ein Standardobjekt mit vielen möglichen Anpassungen erstellen möchten, in der Regel jedoch nur wenige anpassen.
Wenn Sie beispielsweise einen HTTP-Client schreiben möchten, richten Sie einige Standardparameter wie Standard-Schreib- / Lesezeitlimit, Protokolle, Cache, DNS, Interceptors usw. ein.
Die meisten Benutzer Ihres Clients verwenden nur diese Standardparameter, während einige andere Benutzer möglicherweise einige der anderen Parameter anpassen möchten. In einigen Fällen möchten Sie nur die Zeitüberschreitungen ändern und den Rest unverändert verwenden. In anderen Fällen müssen Sie möglicherweise beispielsweise den Cache anpassen.
Es gibt folgende Möglichkeiten, Ihren Client zu instanziieren (aus OkHttpClient):
Wenn Sie hierfür ein Factory-Muster verwenden, werden Sie am Ende viele Methoden mit allen möglichen Kombinationen von Erstellungsparametern schreiben. Mit dem Builder geben Sie einfach diejenigen an, die Sie interessieren, und lassen den Builder sie für Sie erstellen, wobei Sie sich um all diese anderen Parameter kümmern.
quelle
Das Erstellungsmuster betont die Komplexität des Erstellens eines Objekts (gelöst durch "Schritte").
Das abstrakte Muster betont "nur" die "Abstraktion" von (mehreren, aber verwandten) Objekten.
quelle
Der Unterschied ist klar. Im Builder-Muster erstellt der Builder einen bestimmten Objekttyp für Sie. Sie müssen sagen, was der Builder bauen muss. Im Factory-Muster erstellen Sie mit der abstrakten Klasse direkt das spezifische Objekt.
Hier fungiert die Builder-Klasse als Vermittler zwischen der Hauptklasse und bestimmten Typklassen. Mehr Abstraktion.
quelle
Beide sind sich sehr ähnlich. Wenn Sie jedoch eine große Anzahl von Parametern für die Objekterstellung haben, von denen einige optional sind und einige Standardwerte aufweisen, wählen Sie das Builder-Muster.
quelle
meiner bescheidenen Meinung nach
Builder ist eine Art komplexere Fabrik.
Aber in Builder können Sie Objekte instanziiert mit anderen Fabriken verwenden , die erforderlich sind , endgültig und gültiges Objekt zu bauen.
Wenn Sie also über die Entwicklung von "Schöpfungsmustern" nach Komplexität sprechen, können Sie folgendermaßen darüber nachdenken:
quelle
Beide Muster haben die gleiche Notwendigkeit: Verstecken Sie die Konstruktionslogik eines komplexen Objekts vor einem Client-Code. Aber was macht "komplex" (oder manchmal kompliziert) ein Objekt? Hauptsächlich liegt es an Abhängigkeiten oder vielmehr am Zustand eines Objekts, das aus mehr Teilzuständen besteht. Sie können Abhängigkeiten nach Konstruktor einfügen, um den anfänglichen Objektstatus festzulegen. Für ein Objekt sind jedoch möglicherweise viele erforderlich. Einige befinden sich in einem anfänglichen Standardzustand (nur weil wir hätten lernen müssen, dass das Festlegen einer Standardabhängigkeit auf null nicht der sauberste Weg ist ) und eine andere Einstellung in einen Zustand, der von einer bestimmten Bedingung bestimmt wird. Darüber hinaus gibt es Objekteigenschaften, die eine Art "ahnungslose Abhängigkeiten" darstellen, aber auch optionale Zustände annehmen können.
Es gibt zwei bekannte Möglichkeiten, diese Komplexität zu beherrschen:
Zusammensetzung / Aggregation: Konstruieren Sie ein Objekt, konstruieren Sie seine abhängigen Objekte und verbinden Sie es dann. Hier kann ein Builder den Prozess, der die Regeln für die Konstruktion von Komponenten festlegt, transparent und flexibel gestalten.
Polymorphismus: Konstruktionsregeln werden direkt in der Subtypdefinition deklariert, sodass Sie für jeden Subtyp eine Reihe von Regeln haben und eine Bedingung entscheidet, welche dieser Regeln für die Konstruktion des Objekts gelten. Eine Fabrik passt perfekt in dieses Szenario.
Nichts hindert daran, diese beiden Ansätze zu vermischen. Eine Produktfamilie kann die mit einem Builder erstellte Objekterstellung abstrahieren. Ein Builder kann mithilfe von Fabriken bestimmen, welches Komponentenobjekt instanziiert wird.
quelle
Meiner Meinung nach wird das Builder-Muster verwendet, wenn Sie ein Objekt aus einer Reihe anderer Objekte erstellen möchten und die Erstellung eines Teils unabhängig von dem Objekt sein muss, das Sie erstellen möchten. Es ist hilfreich, die Erstellung von Teilen vor dem Client zu verbergen, um Builder und Client unabhängig zu machen. Es wird für die Erstellung komplexer Objekte verwendet (Objekte, die aus komplizierten Eigenschaften bestehen können).
Während das Factory-Muster angibt, dass Sie Objekte einer gemeinsamen Familie erstellen möchten und diese sofort bearbeitet werden sollen. Es wird für einfachere Objekte verwendet.
quelle
Von: http://www.oodesign.com/builder-pattern.html
quelle
Das Factory-Muster erstellt zur Laufzeit eine konkrete Implementierung einer Klasse, dh die Hauptabsicht besteht darin, mithilfe des Polymorphismus zu entscheiden, welche Klasse instanziiert werden soll. Dies bedeutet, dass wir zur Kompilierungszeit nicht genau wissen, welche Klasse erstellt wird, während sich das Builder-Muster hauptsächlich mit der Lösung des Problems des Antipatterns von Teleskopkonstruktoren befasst, das aufgrund einer großen Anzahl optionaler Felder einer Klasse auftritt. Im Builder-Muster gibt es keine Vorstellung von Polymorphismus, da wir wissen, welches Objekt wir zur Kompilierungszeit konstruieren möchten.
Das einzige gemeinsame Thema dieser beiden Muster ist das Ausblenden von Konstruktoren und die Objekterstellung hinter Factory-Methoden sowie die Build-Methode für eine verbesserte Objektkonstruktion.
quelle
Mit dem Factory-Muster können Sie ein Objekt sofort erstellen, während Sie mit dem Builder-Muster den Erstellungsprozess eines Objekts unterbrechen können. Auf diese Weise können Sie beim Erstellen eines Objekts verschiedene Funktionen hinzufügen.
quelle