Ich habe ein kleines Dilemma mit Guice und Vermeidung von Nicht-Guice Singletons. Stellen Sie sich ein Projekt mit mehreren Modulen vor, in dem 3 Module vorhanden sind: shared
, frontend
und backend
. Sowohl die frontend
als auch die backend
verwenden eine Instanz einer Profiling
Klasse innerhalb des shared
Moduls (welche Zeiten Methoden, und wird umfangreich während des Projekts verwendet).Verwendung der Dependency-Injektion (über Guice) in einer Multi-Modul-Umgebung
Fast jede einzelne Klasse erfordert die Verwendung dieser Profiling
-Instanz (einschließlich User
Objekte, die dynamisch erstellt werden, wenn ein Benutzer eine Verbindung herstellt).
Wenn jede einzelne Klasse eine Instanz der Profiling
Klasse erfordert, gibt es Nachteile der verschiedenen Methoden, es zu tun:
Lösung 1 (im Konstruktor auf die Instanz Feld kopiert):
private final Profiling profiling;
@Inject
public User(Profiling profiling, String username)
Nachteil: Sie müssen ein Profiling
Objekt in jeden einzelnen Konstruktor einfügen. Dies ist umständlich und leicht sinnlos. Sie müssen auch Guices Injector
statisch speichern (oder es injizieren), so dass Sie die User
Objekte on-the-fly erstellen können und nicht nur, wenn das Programm zum ersten Mal geladen wird.
Lösung 2 (als Beispiel Feld nur):
@Inject
private Profiling profiling;
public User(String username)
Drawback: Ähnlich wie oben, haben Sie Injector
Guice zu gebrauchen jedes einzelne Objekt zu instanziiert. Dies bedeutet, dass zur dynamischen Erstellung von User
Objekten eine Instanz des Injektors in der Klasse benötigt wird, die die Objekte User
erzeugt.
Lösung 3 (als ein statisches Feld in einem (Haupt-) Klasse, manuell von uns erstellt)
public static final Profiling PROFILING; // Can also use a get method
public Application() {
Application.PROFILING = injector.getInstance(Profiling.class)
}
Drawback: geht gegen Guice/der Abhängigkeitsinjektions Empfehlungen - Erstellen einer Singleton Profiling
Objekt, das statisch zugegriffen wird (von Application.PROFILING.start()
) besiegt den Zweck von Guice?
Lösung 4 (als statisches Feld in jeder einzelnen Klasse, injiziert durch Guice)
@Inject
private static Profiling profiling;
// You need to request every single class:
// requestStaticInjection(XXXX.class)
Nachteil: Auch dies geht gegen Guice/der Dependency Injection Empfehlungen, weil es statisch einspritzt. Ich muss auch jede einzelne Klasse anfordern, die Guice benötigt, um den Profiler zu injizieren (was auch mühsam ist).
Gibt es einen besseren Weg, um mein Projekt zu entwerfen und zu vermeiden, auf die Singleton-Entwurfsmuster zurückzugreifen, die ich verwendet habe?
TL; DR: Ich möchte auf diese Profiling-Instanz (eine pro Modul) über jede einzelne Klasse zugreifen können, ohne auf Singleton-Entwurfsmuster zurückzugreifen.
Danke!
Ich würde es in jede Guice-Managed-Klasse injizieren, wie Sie vorgeschlagen (nicht statisch). Ich würde nur Constructor-Injection verwenden (weil das erzwingt, dass eine manuelle Konstruktion dieselben Argumente übergeben muss und keine ungültige Instanz erstellen kann). Der Benutzer klingt jedoch nicht wie eine von Hand verwaltete Klasse. Ich würde (vielleicht gibt es hier nicht genug Informationen) dies über eine User-Factory implementieren, die mit der Profiling-Klasse injiziert werden kann und das Problem, eine Profiling-Instanz in jedem Benutzer zu haben, abstrahiert. – pandaadb