2010-06-25 6 views
7

Ich habe gelesen, effektive Java und ich habe Bedenken in Bezug auf das erste Element "verwenden statische Factory-Methode anstelle von Konstruktor" in Bezug auf TDD und Abhängigkeitsinjektion.Effektive Java Element 1 Anwendbarkeit mit TDD und Abhängigkeitsinjektion

Das Element besagt, dass Sie vermeiden sollten, öffentliche/protected/default-Konstruktor und expose es mit statischen Factory. Ich stimme allen Vorteilen im Zusammenhang mit der Verwendung von statischen Fabriken wie Fabriken Namen haben, können Sie Subtype zurückgeben, können Sie Ausführlichkeit etc. reduzieren. Aber, ich denke in Nachteile Joshua vermisste TDD, weil statische Fabriken in Ihrem Code zu führen enge Kopplung und Sie können die Klasse nicht damit verspotten. Wir können nicht die Klasse vortäuschen, die statische Fabriken haben wird. Dies behindert die testgetriebene Entwicklung.

Zweiter Punkt, ich denke, er vermisste, dass in der heutigen Unternehmensentwicklung die meisten der Anwendungen den einen oder anderen Abhängigkeitsinjektionscontainer verwenden. Also, wenn wir Abhängigkeiten mit DI injizieren können, warum sollte ich es verwenden.

Bitte erläutern Sie, wie es für die heutige Java-Unternehmensentwicklung gilt, die DI und TDD enthält.

Antwort

3

Ich sehe zwei getrennte Fragen hier:

  • statische Fabriken vs mit neuer()
  • Dependency Injection

Wenn Ihr Code mit neuen wie eng gekoppelt ist als eine statische Methode unter Verwendung von Tatsächlich ist es sogar noch schlimmer, da die statische Fabrik etwas Magie ausführen und eine bestimmte Implementierung zurückgeben kann, solange es sich um eine Unterklasse oder eine Implementierung einer Schnittstelle handelt.

Mit Abhängigkeitsinjektion wird das Prinzip auch das Hollywood-Prinzip genannt: "Ruf uns nicht an, wir rufen dich an". Also, in dieser Philosophie solltest du nicht neu() oder die statische Fabrik in deinem Code nennen, sondern eine externe Sache, die das für dich tut, entweder das DI-Framework oder den Komponententest. Das hat nichts mit Fabriken oder der Verwendung von neuen zu tun, wie das anderswo gemacht wird.

In diesem Fall sind Fabriken besser, weil Sie eine Testfabrik unter Ihrer Kontrolle injizieren können. Mit new ist das nicht möglich (ohne merkwürdige Dinge für den Klassenpfad zu tun, wie das Verstecken der Implementierung mit Dummy-Objekten im Test-Klassenpfad, was ich nicht weiter empfehlen kann).

4

Der DI-Motor ist das Werk.

Joshua Bloch versteht DI gut genug. Ich denke, das ist ein Artefakt der Geschichte, denn der Aufstieg von DI kam nach der ersten Ausgabe von "Effective Java".

"Effektive Java" war published in 2001. Martin Fowler prägte den Begriff im Jahr 2004. Spring's 1.0 release kam im März 2004.

Joshua Bloch hat dieses Kapitel für die zweite Ausgabe nicht geändert.

Der Punkt ist die Kopplung, die "neu" einführt. Wer das und die Fabriken versteht, wird den Sprung zu den DI-Motoren schaffen. Der Punkt ist, dass seine Aussagen über "neu" und das Mittel, Fabriken zu benutzen, immer noch wahr sind.

+0

Ich glaube nicht, dass Sie meine Frage bekommen. Die Frage ist nicht, dass wir neue Kopplung einführen und wir sollten statische Fabriken verwenden. Es geht um seine Anwendbarkeit in der heutigen Unternehmensentwicklung. Ich sage nicht, dass Joshua Bloch DI nicht kennt. Bitte antworten Sie auf das, was ich in meiner Frage frage. Zweite Ausgabe veröffentlicht im Mai 2008 – Shekhar

+0

Ich weiß, wann die zweite Ausgabe veröffentlicht wurde. Ich sage, dass er dieses Kapitel einfach nicht aktualisiert hat. Und "Nachteile Joshua vermisste TDD" ließ mich schließen, dass Sie sagten, dass Bloch DI nicht kannte. – duffymo

0

Ich hatte die gleiche Sorge, die Sie haben, und so habe ich Ihre Frage gefunden.

Sie sagen:

weil in Ihrem Code statische Fabriken hat, wird zu eng Kopplung führen und die Klasse nicht spotten kann mit ihm

das Buch zeigt, dass Sie die aussetze Konstruktor Ihrer Klasse mit einer statischen Methode (api-Design). Es schlägt nicht vor, dass Sie "hardcode" den statischen Anruf über Ihre gesamte Anwendung (API-Nutzung).

Angenommen, Sie Guice für DI verwenden und Ihre Schnittstelle Connection genannt wird, die Sie tun können:

bind(Connection.class).toInstance(Connections.makeASpecificConnection(params)); 

Und dann Ihre übliche @Inject Connection connection;

Natürlich ist dies, wenn Ihre Verbindung ein Singleton ist. Wenn dies nicht der Fall ist, können Sie eine Abstract Factory mit einer Implementierung injizieren, die Instanzen erstellt, die die statische Methode Ihrer Klasse aufrufen, aber dies könnte viel zu viel Aufwand sein und Sie würden Guice besser allein verwenden.

Denken Sie daran, dass dieses Buch nicht in erster Linie auf den Aufbau von großen Unternehmensanwendungen ausgerichtet ist, obwohl es immer noch sehr hilfreich ist. Zitat aus dem Vorwort des Buches:

Während dieses Buch richtet sich nicht nur an Entwickler von wieder verwendbaren Komponenten wird zwangsläufig durch meine Erfahrung schreiben solche Komponenten in den letzten zwei Jahrzehnten gefärbt. Ich denke natürlich in Bezug auf exportierte APIs (Application Programming Interfaces), und ich ermutige , Sie ebenfalls zu tun.

Verwandte Themen