it-swarm.com.de

Warum ist das Entwurfsmuster der Factory-Methode nützlicher, als Klassen zu haben und sie einzeln aufzurufen?

Aus den "Gang of Four" -Designmustern gibt es die Factory-Methode:

class Factory(product)
  case product
  when a
    new A
  when b
    new B
  when c
    new C
end

new Factory(a)

Warum ist dies nützlicher, als drei Klassen zu haben, a, b und c und sie einzeln aufzurufen?

33
alt

Weil Ihr Beispiel nicht kompliziert genug ist. Für ein so einfaches Szenario ist es nicht einmal sinnvoll, ein erweitertes Muster zu verwenden.

Wenn Sie jedoch mehr als das Produkt wissen müssen, um A, B oder C zu konstruieren, und keinen direkten Zugriff auf dieses Wissen haben, ist dies hilfreich. Dann nutzen Sie die Fabrik als Wissenszentrum für die Herstellung der benötigten Objekte.

Möglicherweise benötigen diese Objekte einen Verweis auf ein Objekt X, das die Factory bereitstellen kann, aber Ihr Code an der Stelle, an der Sie A, B oder C erstellen möchten, kann oder sollte keinen Zugriff auf X haben. Vielleicht, wenn Sie X haben Sie erstellen A und B, aber wenn Sie den Typ Y haben, erstellen Sie C.

Beachten Sie auch, dass für einige Objekte möglicherweise 20 Abhängigkeiten zum Erstellen erforderlich sind. was dann? Die Suche nach diesen Abhängigkeiten an einem Ort, an dem sie nicht zugänglich sein sollten, könnte problematisch sein.

57
Mateusz

Ein Fabrikmuster ist normalerweise komplexer. Eine Fabrik entscheidet über bestimmte Kriterien, welche Instanz erstellt/zurückgegeben werden soll. Wenn Sie die Factory nicht verwenden, wird dieser Code an mehreren Stellen in Ihrem Code wiederholt verwendet.

Betrachten Sie als Beispiel Folgendes: Sie müssen Daten aus einer Datenbank laden, haben jedoch eine zentrale Datenbank für die Integration mit vielen Daten und eine kleinere im Speicher auf jedem Entwicklungs-PC. In Ihrem Code bitten Sie eine Fabrik, a DB-Handle zu erhalten, und die Fabrik gibt eine davon zurück, abhängig von z. eine Konfigurationsdatei.

23
Andy

Das Factory-Methodenmuster abstrahiert den Entscheidungsprozess von der aufrufenden Klasse. Dies hat mehrere Vorteile:

Wiederverwendung. Wenn ich an vielen Stellen instanziieren möchte, muss ich meinen Zustand nicht wiederholen. Wenn ich also komme, um eine neue Klasse hinzuzufügen, muss ich Gehen Sie nicht das Risiko ein, einen zu verpassen.

Unit-Testability. Ich kann 3 Tests für die Factory schreiben, um sicherzustellen, dass die richtigen Typen unter den richtigen Bedingungen zurückgegeben werden, die meine aufrufende Klasse nur benötigt zu testen, um festzustellen, ob die Factory aufgerufen wird, und dann die erforderlichen Methoden für die zurückgegebene Klasse. Es muss nichts über die Implementierung der Fabrik selbst oder der konkreten Klassen wissen.

Erweiterbarkeit. Wenn jemand entscheidet, dass wir dieser Factory eine neue Klasse D hinzufügen müssen, muss keiner der aufrufenden Codes, weder Unit-Tests noch die Implementierung, dies jemals tun erzählt werden. Wir erstellen einfach eine neue Klasse D und erweitern unsere Fabrikmethode. Dies ist genau die Definition von Open-Closed-Prinzip .

Sie können sogar eine neue Factory-Klasse erstellen und diese Hot-Swap-fähig machen, wenn die Situation dies erfordert - beispielsweise, wenn Sie die Klasse D während des Testens ein- und ausschalten möchten. Ich bin nur einmal auf diese Situation gestoßen, aber sie war äußerst nützlich.

Wie bereits gesagt, ist das Fabrikmuster nicht immer der richtige Weg. Aber wo immer Sie bedingte Instanziierung sehen, sollten Sie einen Moment darüber nachdenken.

20
pdr

Das Factory-Muster bietet zwei Hauptvorteile:

  1. Die Stellen, die eine Implementierung des Produkts benötigen, müssen nicht wissen, wie man eine erstellt. Die Fabrik hält diese Informationen.

    Möchten Sie wissen, welche Argumente an den jeweiligen Konstruktor übergeben werden sollen? Oder welche Abhängigkeiten müssen Sie injizieren? Oder wie registriert man die Implementierungsklasse bei der Datenbank, nachdem sie vollständig konfiguriert wurde? Nein? Lassen Sie die Fabrik sich um all das kümmern.

  2. Die Stellen, die eine Implementierung des Produkts benötigen, müssen zum Zeitpunkt der Modulbeschreibung (d. H. Zur Kompilierungszeit) nicht wissen, wie der Name der Implementierungsklasse lautet.

    Somit muss a nichts mit A zu tun haben; Das „Was soll gebaut werden“ kann anhand der gewünschten nicht funktionalen Eigenschaften und nicht nur anhand des Namens beschrieben werden. Das ist viel flexibler.

Der Nachteil ist, dass Sie, wenn Sie wissen, was zu machen ist und wie es zu tun ist, komplexer werden, wenn Sie eine Fabrik nutzen. Die Lösung dafür ist jedoch einfach: Verwenden Sie keine Fabrik, wenn dies keinen Sinn ergibt!

14
Donal Fellows

Ich würde gerne über Designmuster nachdenken, wenn Klassen als „Menschen“ betrachtet werden, und Muster sind Wege, wie Menschen miteinander sprechen.

Für mich ist das Fabrikmuster also wie eine Personalagentur. Sie haben jemanden, der eine variable Anzahl von Arbeitern benötigt. Diese Person kennt möglicherweise einige Informationen, die sie für die von ihnen eingestellten Personen benötigt, aber das war's.

Wenn sie also einen neuen Mitarbeiter benötigen, rufen sie die Personalagentur an und sagen ihnen, was sie brauchen. Um tatsächlich jemanden einstellen zu können, müssen Sie eine Menge Dinge wissen - Vorteile, Überprüfung der Berechtigung usw. Aber die Person, die einstellt, muss nichts davon wissen - die Personalagentur kümmert sich um all das.

Auf die gleiche Weise ermöglicht die Verwendung einer Factory dem Verbraucher, neue Objekte zu erstellen, ohne die Details zu kennen, wie sie erstellt wurden oder welche Abhängigkeiten sie haben - sie müssen nur die Informationen angeben, die sie tatsächlich möchten.

mit freundlicher Genehmigung

2
Premraj

Das Factory-Muster ist das am häufigsten verwendete und missbrauchte Designmuster.

Ich bin auf zahlreiche Fälle gestoßen, in denen eine Factory-Klasse codiert ist, wenn ein einfacher Konstruktor angemessen wäre.

Verwenden Sie keine Fabrikklasse, es sei denn: -

  • Sie sind auf eine externe Ressource angewiesen, wissen aber noch nicht genau, welche.
  • Der Bau ist teuer und Sie möchten einmal bauen und viele Male wiederverwenden.
  • Das Erstellen einer neuen Instanz hängt davon ab, welche Instanzen bereits erstellt wurden (z. B. Sie können nur fünf Verbindungen haben, oder Sie sollten eine Verbindungs-ID Nummer eins mehr als die zuletzt verwendete Nummer verwenden).
1
James Anderson

Verwenden Sie die Factory-Methode, wenn Sie eine Unterklasse instanziieren, und der Client-Code soll nicht dafür verantwortlich sein, zu entscheiden, welche bestimmte Unterklasse instanziiert wird.

Dies ist nützlich, da Sie den Clientcode nicht ändern müssen, wenn Sie ändern müssen, welche Klasse instanziiert wird. Das Ändern von vorhandenem Code ist eine schlechte Praxis, da er normalerweise fehleranfällig ist.

Ein Beispiel wären Unterklassen, in denen die Daten in aufsteigender Reihenfolge sortiert werden, jedoch auf andere Weise. Jeder Weg ist für eine bestimmte Art von Daten optimal. Beispiel: teilweise sortierte Daten, Daten, die Zahlen usw. sind. Der Client-Code ist eine Klasse, die nur das Drucken von Daten behandelt. Wenn Code vorhanden ist, der entscheidet, welche Sortierklasse in der Clientklasse instanziiert wird, wird dies zu einer komplexen Klasse. Mit anderen Worten, in diesem Fall mehr als eine Verantwortung zu haben, zu entscheiden, welche Sortierklasse optimal ist, und Daten zu drucken. Indem Sie den Code, der entscheidet, welche Sortierklasse instanziiert wird, in eine Factory-Klasse einfügen, werden die Bedenken getrennt, sodass Sie die Client-Klasse nicht jedes Mal ändern müssen, wenn Sie ändern müssen, welche Sortierunterklasse instanziiert wird.

Es ist eine Möglichkeit, deinen Arsch zu bedecken. Wenn du vorhersehen kannst, wie oder welche Klasse instanziiert wird, ist es sinnvoll, Factory-Klassen zu verwenden. Dies hilft, Ihre Klassen auf ihre einzige Verantwortung zu konzentrieren, und stellt somit sicher, dass Sie weniger wahrscheinlich vorhandenen Code ändern müssen, der nicht in Beziehung steht.

0
kiwicomb123