18

Ich versuche kurz zu beschreiben wenn eine Fabrik zu verwenden, für mich und mein Team. Ich lief über die folgenden verwandten Fragen, die etwas geholfen:Wann das abstrakte Fabrikmuster verwenden?

Basierend auf diesen Links und eine Reihe von anderen Quellen (unten aufgeführt), ich habe mit dem kommen folgende:

Wenn die abstrakte verwenden Fabrik Muster:

  • wenn Sie eine Schnittstelle var oder den 'neuen' Operator
    • , z.B. Benutzer user = new ConcreteUserImpl();
  • und der Code, den Sie an einem gewissen Punkt

Erklärung prüfbar/erweiterbar sein schreiben soll:

  • Schnittstellen, die von ihrer Natur impliziert mehrere Implementierungen (gut für Unit-Tests)
  • Schnittstelle vars implizieren OCP- und LSP-konformen Code (Unterstützung Sub-Classing)
  • Verwendung des ‚neuen‘ Betreiber bricht OCP/DI, weil hoch gekoppelt Klassen sind hart

„zu testen oder ändern Muss ich eine Fabrik für jeden Objekttyp erstellen? Das scheint übertrieben."

  • nicht, können Sie eine (oder wenige) haben Fabriken, die eine Menge (in der Regel im Zusammenhang) Objekttypen
  • zB appFactory.createUser() zu erzeugen; appFactory.createCatalog(); usw.

Wenn keine Fabrik zu verwenden:

  • das neue Objekt ist sehr einfach und es ist unwahrscheinlich Unter eingestuft 0 sein
    • z.B. Listenliste = new ArrayList();
  • das neue Objekt ist nicht interessant
    • zu testen, hat keine Abhängigkeiten
    • führt keine relevanten oder lang andauernde Arbeit
    • z.B. Loggerprotokoll = neu SimpleLogger();

Referenzen:


Meine Frage ist: ist meine Zusammenfassung genau und macht es Sinn? Gibt es etwas, was ich übersehen habe?

Vielen Dank im Voraus.

+1

Warum ist dieses Java verwandt? Sollte es nicht sprachunabhängig sein? –

+0

@the_drow: behoben, danke. – Luke

+0

Ich hasse das Wiederbeleben alter Threads, aber ... Ich stimme nicht zu, dass Logger wie oben new'd neu sein sollten. Ich betreibe oft verschiedene Logger in verschiedenen Testumgebungen. Ich konfiguriere die Umgebung für die Verwendung eines bestimmten Loggers und injiziere ihn in Objekte, die loggen. (Ich könnte sogar Arrays von Loggern injizieren.) – aridlehoover

Antwort

1

Abstract Factory-Muster bietet eine Möglichkeit, konkrete Fabriken mit Gemeinsamkeiten zu kapseln, dh sie implementieren dieselbe Schnittstelle/abstrakte Klasse.

Sie müssen das Fabrikmuster immer dann verwenden, wenn Sie die Initialisierung Ihrer Objekte steuern möchten, anstatt dem Verbraucher die Kontrolle zu geben.

5

Ich würde auch sagen, verwenden Sie keine Fabrik, wenn Sie eine bestimmte Implementierung haben, die Sie wollen. Um das List Beispiel fortzusetzen, weiß ich, dass ich eine ArrayList möchte, weil ich einen wahlfreien Zugriff mache. Ich möchte mich nicht darauf verlassen, dass eine Fabrik das richtig macht, wenn ich es selbst machen kann.

Umgekehrt kann ich, wenn ich nichts über die konkrete Unterklasse wissen will, eine Fabrik verwenden und sich darum kümmern, welches Objekt tatsächlich instanziiert wird.

Ich schlage vor, dass Sie eine Kugel hinzufügen, um das "Wann das abstrakte Fabrikmuster zu verwenden", das sagt "und Sie nicht wirklich welche konkrete Unterklasse Sie erhalten" und das Gegenteil zu "wenn nicht eine Fabrik benutzen ".

EDIT: Seien Sie vorsichtig, die general-purpose tool-building factory factory factory zu vermeiden.

+0

Ok - sagen wir, ich wollte die spezifischen Vorteile eines zwischengespeicherten Thread-Pools: ExecutorService pool = Executors.newCachedThreadPool(); In meinen Unit-Tests (aus welchen Gründen auch immer) bin ich nicht an den Ergebnissen der im Pool geleisteten Arbeit interessiert, und ich möchte nicht warten müssen, bis die Arbeit bei jedem Test beendet ist . Würde ich dann noch eine Fabrik benutzen, damit ich meinen Thread-Pool für Tests stöbern könnte? Es scheint mir, dass wenn Sie in Betracht ziehen zu testen, möchten Sie an ** die meisten ** Ihres Codes denken als nicht kümmern sich um die tatsächliche Implementierung, damit Sie nicht überprüfbaren Code schreiben. – Luke

+0

Ja, das ist richtig. Im Allgemeinen interessiert sich der Großteil Ihres Codes nicht für die tatsächliche Implementierung. Die Wahl zwischen'ArrayList' und 'LinkedList' ist eine der wenigen Möglichkeiten, die Sie interessieren, da sie unterschiedliche Leistungsmerkmale haben. Sie haben recht: Zum Testen ist es am besten, die tatsächliche Implementierung so gut wie möglich zu ignorieren. –

+1

+1 nur für den Link. –

3

Im Allgemeinen verwenden Sie es, wenn Sie in der Lage sein möchten, die Implementierung durch externe Konfiguration zu wechseln.

JDBC und JAXP sind ausgezeichnete Beispiele. Weitere Beispiele finden Sie unter this answer.

+0

Würde das nicht bedeuten, einen IoC-Container zu verwenden? – dexter

+0

@ Max: nicht unbedingt. – BalusC

+0

Könnten Sie bitte näher erläutern, wann Sie Ihre benutzerdefinierte Fabrik im Vergleich zu einem IoC verwenden würden, um den Objekttyp per Config zu wechseln? – dexter

Verwandte Themen