Ich weiß, dass es viele Posts über die Unterschiede zwischen diesen beiden Mustern gibt, aber es gibt einige Dinge, die ich nicht finden kann.
Nach dem, was ich gelesen habe, können Sie anhand des Factory-Methodenmusters definieren, wie ein einzelnes konkretes Produkt erstellt werden soll, die Implementierung jedoch vor dem Client ausgeblendet werden, da ein generisches Produkt angezeigt wird. Meine erste Frage betrifft die abstrakte Fabrik. Ist es seine Aufgabe, es Ihnen zu ermöglichen, Familien von konkreten Objekten in (die von der von Ihnen verwendeten Fabrik abhängen können) und nicht nur ein einzelnes konkretes Objekt zu erstellen? Gibt die abstrakte Factory nur ein sehr großes Objekt oder mehrere Objekte zurück, je nachdem, welche Methoden Sie aufrufen?
Meine letzten beiden Fragen beziehen sich auf ein einzelnes Zitat, das ich an zahlreichen Stellen nicht vollständig verstehen kann:
Ein Unterschied zwischen beiden besteht darin, dass beim Abstract-Factory-Muster eine Klasse die Verantwortung für die Objektinstanziierung über die Komposition an ein anderes Objekt delegiert, während das Factory-Methodenmuster die Vererbung verwendet und sich auf eine Unterklasse stützt, um die gewünschte Objektinstanziierung zu handhaben.
Ich verstehe, dass das Factory-Methodenmuster über eine Creator-Schnittstelle verfügt, über die der ConcreteCreator weiß, welches ConcreteProduct instanziiert werden soll. Bedeutet dies, dass die Verwendung der Vererbung zur Handhabung der Objektinstanziierung verwendet wird?
Wie genau delegiert das Abstract Factory-Muster in Bezug auf dieses Zitat die Verantwortung für die Objektinstanziierung über die Komposition an ein anderes Objekt? Was bedeutet das? Es sieht so aus, als ob das Abstract Factory-Muster in meinen Augen auch Vererbung verwendet, um den Konstruktionsprozess durchzuführen, aber andererseits lerne ich immer noch etwas über diese Muster.
Jede Hilfe, insbesondere bei der letzten Frage, wäre sehr dankbar.
quelle
Antworten:
Der Unterschied zwischen den beiden
Der Hauptunterschied zwischen einer "Factory-Methode" und einer "abstrakten Factory" besteht darin, dass die Factory-Methode eine einzelne Methode ist und eine abstrakte Factory ein Objekt ist. Ich denke, viele Leute verwechseln diese beiden Begriffe und verwenden sie austauschbar. Ich erinnere mich, dass es mir schwer fiel, genau herauszufinden, was der Unterschied war, als ich sie lernte.
Da die Factory-Methode nur eine Methode ist, kann sie in einer Unterklasse überschrieben werden, daher die zweite Hälfte Ihres Angebots:
Das Zitat geht davon aus, dass ein Objekt hier seine eigene Factory-Methode aufruft . Daher wäre das einzige, was den Rückgabewert ändern könnte, eine Unterklasse.
Die abstrakte Factory ist ein Objekt, das mehrere Factory-Methoden enthält. Betrachten Sie die erste Hälfte Ihres Zitats:
Sie sagen, dass es ein Objekt A gibt, das ein Foo-Objekt erstellen möchte. Anstatt das Foo-Objekt selbst zu erstellen (z. B. mit einer Factory-Methode), wird ein anderes Objekt (die abstrakte Factory) zum Erstellen des Foo-Objekts verwendet.
Codebeispiele
Um Ihnen den Unterschied zu zeigen, wird hier eine Factory-Methode verwendet:
Und hier ist eine abstrakte Fabrik im Einsatz:
quelle
SpecialFoo
, um klarer zu sein.Abstract Factory erstellt eine Basisklasse mit abstrakten Methoden, die Methoden für die Objekte definieren, die erstellt werden sollen. Jede Factory-Klasse, die die Basisklasse ableitet, kann für jeden Objekttyp eine eigene Implementierung erstellen.
Die Factory-Methode ist nur eine einfache Methode zum Erstellen von Objekten in einer Klasse. Es wird normalerweise im aggregierten Stamm hinzugefügt (Die
Order
Klasse hat eine Methode namensCreateOrderLine
)Abstrakte Fabrik
Im folgenden Beispiel entwerfen wir eine Schnittstelle, damit wir die Warteschlangenerstellung von einem Messagingsystem entkoppeln und daher Implementierungen für verschiedene Warteschlangensysteme erstellen können, ohne die Codebasis ändern zu müssen.
Fabrikmethode
Das Problem bei HTTP-Servern ist, dass wir für jede Anfrage immer eine Antwort benötigen.
Ohne die Factory-Methode wären die Benutzer des HTTP-Servers (dh Programmierer) gezwungen, implementierungsspezifische Klassen zu verwenden, die den Zweck der
IHttpRequest
Schnittstelle zunichte machen.Daher führen wir die Factory-Methode ein, damit auch die Erstellung der Antwortklasse abstrahiert wird.
Zusammenfassung
Der Unterschied besteht darin, dass der beabsichtigte Zweck der Klasse, die eine Factory-Methode enthält, nicht darin besteht, Objekte zu erstellen , während eine abstrakte Factory nur zum Erstellen von Objekten verwendet werden sollte.
Bei der Verwendung von Factory-Methoden ist Vorsicht geboten, da es beim Erstellen von Objekten leicht ist, das LSP ( Liskov Substitution-Prinzip ) zu brechen .
quelle
Button()
eine "Familie verwandter Produkte" schaffen. Das kanonische GoF-Beispiel erstellt beispielsweiseScrollBar()
undWindow()
. Der Vorteil ist, dass die Abstract Factory ein gemeinsames Thema für mehrere Produkte durchsetzen kann.Der Unterschied zwischen AbstractFactory- und Factory-Entwurfsmustern ist wie folgt:
Implementierung des Factory-Methodenmusters:
Implementierung des abstrakten Fabrikmusters:
quelle
Der Hauptunterschied zwischen Abstract Factory und Factory Method besteht darin, dass Abstract Factory von Composition implementiert wird . Die Factory-Methode wird jedoch durch Vererbung implementiert .
Ja, Sie haben das richtig gelesen: Der Hauptunterschied zwischen diesen beiden Mustern ist die alte Debatte zwischen Komposition und Vererbung .
UML-Diagramme finden Sie im Buch (GoF). Ich möchte Codebeispiele bereitstellen, da ich denke, dass die Kombination der Beispiele aus den beiden wichtigsten Antworten in diesem Thread eine bessere Demonstration ergibt als jede Antwort allein. Zusätzlich habe ich Terminologie aus dem Buch in Klassen- und Methodennamen verwendet.
Abstrakte Fabrik
Fabrikmethode
ConcreteCreator
ist der Kunde. Mit anderen Worten, der Client ist eine Unterklasse, deren übergeordnetes Element das definiertfactoryMethod()
. Aus diesem Grund sagen wir, dass die Factory-Methode durch Vererbung implementiert wird.Creator
(übergeordnete) Klasse ihre eigene aufruftfactoryMethod()
. Wenn wiranOperation()
aus der übergeordneten Klasse entfernen und nur eine einzige Methode zurücklassen, ist dies nicht mehr das Factory-Methodenmuster. Mit anderen Worten, die Factory-Methode kann nicht mit weniger als zwei Methoden in der übergeordneten Klasse implementiert werden. und einer muss den anderen anrufen.Sonstiges & Verschiedene Fabrikmuster
Beachten Sie, dass die GoF zwar zwei verschiedene Factory-Muster definiert, dies jedoch nicht die einzigen existierenden Factory-Muster sind. Sie sind nicht unbedingt die am häufigsten verwendeten Factory-Muster. Ein berühmtes drittes Beispiel ist Josh Blochs Static Factory Pattern von Effective Java. Das Head First Design Patterns-Buch enthält noch ein weiteres Muster, das sie Simple Factory nennen.
Gehen Sie nicht in die Falle, wenn Sie davon ausgehen, dass jedes Factory-Muster mit einem Muster aus dem GoF übereinstimmen muss.
quelle
factoryMethod()
immer dieprotected
Methode im "Factory Method" -Muster sein? (Ich denke ja)public
Factory-Methoden, und die Methode muss nicht einmal seinabstract
; Der kritische Punkt ist jedoch, dass die Methode für die Vererbung vorgesehen ist und daher (static
oder ) nicht entweder oder sein kannfinal
. Ich habe die Methode gemachtprotected
undabstract
hier, um die (erforderliche) Erweiterbarkeit hervorzuheben.Abstract Factory ist eine Schnittstelle zum Erstellen verwandter Produkte, die Factory-Methode ist jedoch nur eine Methode. Abstract Factory kann mit mehreren Factory-Methoden implementiert werden.
quelle
Betrachten Sie dieses Beispiel zum leichteren Verständnis.
Was bieten Telekommunikationsunternehmen? Zum Beispiel Breitband, Telefonleitung und Mobilfunk, und Sie werden gebeten, eine Anwendung zu erstellen, um ihren Kunden ihre Produkte anzubieten.
Im Allgemeinen würden Sie hier die Produkte erstellen, dh Breitband, Telefonleitung und Mobiltelefon über Ihre Factory-Methode, bei der Sie wissen, welche Eigenschaften Sie für diese Produkte haben, und dies ist ziemlich einfach.
Jetzt möchte das Unternehmen seinen Kunden ein Bündel ihrer Produkte anbieten, dh Breitband, Telefonleitung und Mobiltelefon insgesamt, und hier kommt die Abstract Factory zum Spielen.
Abstract Factory ist mit anderen Worten die Zusammensetzung anderer Fabriken, die für die Herstellung ihrer eigenen Produkte verantwortlich sind, und Abstract Factory weiß, wie diese Produkte in Bezug auf ihre eigenen Verantwortlichkeiten aussagekräftiger platziert werden können.
In diesem Fall ist die
BundleFactory
ist die abstrakte Fabrik,BroadbandFactory
,PhonelineFactory
undMobileFactory
istFactory
. Zur weiteren Vereinfachung verfügen diese Fabriken über die Factory-Methode zur Initialisierung der einzelnen Produkte.Siehe das folgende Codebeispiel:
Hoffe das hilft.
quelle
static
In beiden GoF-Factory-Mustern gibt es keine Methoden. Das ist falsch.Beispiel aus dem wirklichen Leben. (Leicht zu erinnern)
Fabrik
Stellen Sie sich vor, Sie bauen ein Haus und nähern sich einem Zimmermann für eine Tür. Sie geben das Maß für die Tür und Ihre Anforderungen an, und er wird eine Tür für Sie bauen. In diesem Fall ist der Schreiner eine Fabrik für Türen. Ihre Spezifikationen sind Eingaben für die Fabrik, und die Tür ist die Ausgabe oder das Produkt von der Fabrik.
Abstrakte Fabrik
Betrachten Sie nun das gleiche Beispiel der Tür. Sie können zu einem Schreiner gehen, oder Sie können zu einem Plastiktürgeschäft oder einem PVC-Geschäft gehen. Alle von ihnen sind Türfabriken. Abhängig von der Situation entscheiden Sie, an welche Art von Fabrik Sie sich wenden möchten. Dies ist wie eine abstrakte Fabrik.
Ich habe hier sowohl das Factory-Methodenmuster als auch das abstrakte Factory-Muster erklärt, indem ich sie nicht verwendet habe, um Probleme zu erklären, und dann Probleme mithilfe der obigen Muster https://github.com/vikramnagineni/Design-Patterns/tree/master gelöst habe
quelle
Lassen Sie uns klarstellen, dass wir im Produktionscode die meiste Zeit ein abstraktes Factory-Muster verwenden, da Klasse A mit Schnittstelle B programmiert ist. Und A Instanzen von B erstellen muss. A muss also ein Factory-Objekt haben, um Instanzen von B zu erzeugen A ist also nicht von einer konkreten Instanz von B abhängig. Ich hoffe, es hilft.
quelle
Verstehe die Unterschiede in den Motivationen:
Angenommen, Sie erstellen ein Tool, in dem Sie Objekte haben, und eine konkrete Implementierung der Wechselbeziehungen der Objekte. Da Sie Variationen in den Objekten vorhersehen, haben Sie eine Indirektion erstellt, indem Sie die Verantwortung für das Erstellen von Varianten der Objekte einem anderen Objekt zugewiesen haben ( wir nennen es abstrakte Factory ). Diese Abstraktion hat großen Nutzen, da Sie zukünftige Erweiterungen vorhersehen, die Varianten dieser Objekte benötigen.
Eine weitere faszinierende Motivation in diesem Gedankengang ist ein Fall, in dem jedes oder keines der Objekte aus der gesamten Gruppe eine entsprechende Variante aufweist. Unter bestimmten Bedingungen wird eine der Varianten verwendet, und in jedem Fall müssen alle Objekte dieselbe Variante haben. Dies ist möglicherweise etwas kontraintuitiv zu verstehen, da wir häufig der Meinung sind, dass der konkrete Implementierungscode niemals brechen sollte, solange die Varianten eines Objekts einem gemeinsamen einheitlichen Vertrag folgen ( Schnittstelle im weiteren Sinne ). Die faszinierende Tatsache hierbei ist, dass dies nicht immer der Fall ist, insbesondere wenn das erwartete Verhalten nicht durch einen Programmiervertrag modelliert werden kann.
Ein einfaches ( die Idee von GoF entlehnt ) ist eine beliebige GUI-Anwendung, beispielsweise ein virtueller Monitor, der das Erscheinungsbild von MS, Mac oder Fedora-Betriebssystemen emuliert. Wenn hier beispielsweise alle Widget-Objekte wie Fenster, Schaltflächen usw. eine MS-Variante haben, mit Ausnahme einer Bildlaufleiste, die von der MAC-Variante abgeleitet ist, schlägt der Zweck des Tools schlecht fehl.
Diese oben genannten Fälle bilden das Grundbedürfnis von Abstract Factory Pattern .
Stellen Sie sich andererseits vor, Sie schreiben ein Framework, damit viele Benutzer mithilfe Ihres Frameworks verschiedene Tools ( wie das in den obigen Beispielen ) erstellen können. Durch die Idee eines Frameworks müssen Sie dies nicht tun, obwohl Sie keine konkreten Objekte in Ihrer Logik verwenden konnten. Sie legen lieber Verträge auf hoher Ebene zwischen verschiedenen Objekten und deren Interaktion ab. Während Sie ( als Framework-Entwickler ) auf einer sehr abstrakten Ebene bleiben, ist jeder Builder des Tools gezwungen, Ihren Framework-Konstrukten zu folgen. Sie ( die Tool Builder ) können jedoch frei entscheiden, welches Objekt erstellt werden soll und wie alle von ihnen erstellten Objekte interagieren. Im Gegensatz zum vorherigen Fall ( von Abstract Factory Pattern ) sind Sie ( als Framework-Ersteller)) müssen in diesem Fall nicht mit konkreten Objekten arbeiten; und kann vielmehr auf der Vertragsebene der Objekte bleiben. Darüber hinaus haben Sie oder die Werkzeugbauer im Gegensatz zum zweiten Teil der vorherigen Motivationen nie die Situation, Objekte aus Varianten zu mischen. Während der Framework-Code auf Vertragsebene bleibt, ist jeder Tool-Builder ( aufgrund der Art des Falls selbst ) darauf beschränkt, seine eigenen Objekte zu verwenden. Die Objekterstellung wird in diesem Fall an jeden Implementierer delegiert, und Framework-Anbieter bieten lediglich einheitliche Methoden zum Erstellen und Zurückgeben von Objekten. Solche Methoden sind für Framework-Entwickler unumgänglich, um mit ihrem Code fortzufahren, und haben einen speziellen Namen namens Factory-Methode ( Factory Method Pattern für das zugrunde liegende Muster ).
Einige Anmerkungen:
Beispielcode:
quelle
Ja. Die Absicht von Abstract Factory ist:
Im Idealfall sollte pro Objekt, das der Client aufruft, ein Objekt zurückgegeben werden.
Ja. Die Factory-Methode verwendet die Vererbung.
AbstractFactory definiert eine FactoryMethod und ConcreteFactory ist für die Erstellung eines ConcreteProduct verantwortlich. Folgen Sie einfach dem Codebeispiel in diesem Artikel .
Weitere Details finden Sie in verwandten SE-Beiträgen:
Was ist der grundlegende Unterschied zwischen den Factory- und den Abstract Factory-Mustern?
Entwurfsmuster: Factory vs Factory-Methode vs Abstract Factory
quelle
Die Factory-Methode basiert auf der Vererbung: Die Objekterstellung wird an Unterklassen delegiert, die die Factory-Methode zum Erstellen von Objekten implementieren.
Zusammenfassung Factory basiert auf der Objektzusammensetzung: Die Objekterstellung wird in Methoden implementiert, die in der Factory-Oberfläche verfügbar gemacht werden.
Hochrangiges Diagramm des Fabrik- und des abstrakten Fabrikmusters,
Weitere Informationen zur Factory-Methode finden Sie in diesem Artikel .
Weitere Informationen zur Abstract Factory-Methode finden Sie in diesem Artikel .
quelle
Um es mit minimaler Schnittstelle sehr einfach zu machen & bitte konzentrieren Sie sich auf "// 1":
Hier wichtige Punkte: 1. Factory & AbstractFactory-Mechanismen müssen Vererbung verwenden (System.Object-> Byte, Float ...); Wenn Sie also eine Vererbung im Programm haben, ist Factory (Abstract Factory wäre höchstwahrscheinlich nicht vorhanden) bereits von Entwurf 2 vorhanden. Creator (MyFactory) kennt den konkreten Typ und gibt daher ein konkretes Objekt an den Aufrufer (Main) zurück. In abstrakter Fabrik wäre der Rückgabetyp eine Schnittstelle.
Wichtige Punkte: 1. Voraussetzung: Honda würde "Regular", "Sports" erstellen, aber Hero würde "DarkHorse", "Sports" und "Scooty" erstellen. 2. Warum zwei Schnittstellen? Eine für den Herstellertyp (IVehicleFactory) und eine für die Produktfabrik (IVehicle); Eine andere Möglichkeit, 2 Schnittstellen zu verstehen, ist die abstrakte Fabrik, bei der es darum geht, verwandte Objekte zu erstellen. 2. Der Haken ist, dass die Kinder der IVehicleFactory zurückkehren und IVehicle (anstelle von Beton in der Fabrik); so bekomme ich Elternvariable (IVehicle); Dann erstelle ich einen tatsächlichen konkreten Typ, indem ich CreateSingleVehicle aufrufe und dann das übergeordnete Objekt in das tatsächliche untergeordnete Objekt umwandle. Was würde passieren , wenn ich tun
RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");
; Sie erhalten ApplicationException und deshalb benötigen wir eine generische abstrakte Factory, die ich bei Bedarf erläutern würde.quelle
Abstrakte Fabrik : Eine Fabrik von Fabriken; Eine Fabrik, die die einzelnen, aber verwandten / abhängigen Fabriken zusammenfasst, ohne ihre konkreten Klassen anzugeben. Beispiel für eine abstrakte Fabrik
Factory : Es bietet eine Möglichkeit, die Instanziierungslogik an untergeordnete Klassen zu delegieren. Beispiel für ein Fabrikmuster
quelle
Ich würde Abstract Factory jederzeit gegenüber Factory Method bevorzugen. Aus dem obigen Beispiel von Tom Dalling (übrigens eine großartige Erklärung) können wir erkennen, dass Abstract Factory komponierbarer ist, da wir lediglich eine andere Factory an den Konstruktor übergeben müssen (hier verwendete Konstruktorabhängigkeitsinjektion). Für die Factory-Methode müssen wir jedoch eine neue Klasse einführen (mehr Dinge verwalten) und Unterklassen verwenden. Ziehen Sie Komposition immer der Vererbung vor.
quelle
Erlauben Sie mir, es genau auszudrücken. Die meisten Antworten wurden bereits erläutert und enthalten auch Diagramme und Beispiele. Meine Antwort wäre also nur ein Liner. Meine eigenen Worte: - „Das abstrakte Factory-Muster fügt die abstrakte Ebene über mehrere Implementierungen von Factory-Methoden hinzu. bedeutet, dass eine abstrakte Fabrik ein oder mehrere Muster einer Fabrikmethode enthält oder zusammensetzt. “
quelle
Viele der obigen Antworten bieten keine Codevergleiche zwischen dem Muster "Abstract Factory" und "Factory Method". Es folgt mein Versuch, es über Java zu erklären. Hoffe, es hilft jemandem, der eine einfache Erklärung braucht.
quelle