Ich habe zwei Java-Klassen-Dateien. Jeder von ihnen hat Methoden, die der andere verwendet.
%Vor%Die Zeilen
%Vor%und
%Vor%verweisen aufeinander und verursachen eine Endlosschleife, was zu einem java.lang.StackOverflowError-Fehler führt.
Gibt es eine Möglichkeit, die Klassen aufeinander verweisen zu lassen oder habe ich keine andere Wahl, als alle meine Methoden in eine einzige Klasse zu übertragen?
Wie oben gesagt, ist dies ein Zeichen von Code-Geruch.
Ein Setter, der die Methode später setzt, ist nicht zufriedenstellend, da Sie ein Objekt in einem unbestimmten Zustand haben, bis die Setter aufgerufen werden.
Obwohl die Verwendung eines Abhängigkeits-Frameworks wie Spring dazu beitragen kann, das obige Problem zu lösen, können Sie auch keine zyklischen Abhängigkeiten verwenden, wenn Sie die Konstruktorinjektion verwenden. Aber zumindest wenn eine Bohne injiziert wird, ist sie sicher, dass sie nicht zur Hälfte konstruiert ist.
Wenn Sie kein Abhängigkeits-Injection-Framework verwenden möchten, betrachten Sie ein Factory-Muster, bei dem beide Objekte durch eine Factory-Methode erstellt werden, die ein Tupel (oder ein Container-Objekt im Fall von Java ohne native Unterstützung) zurückgibt Tupel), die die vollständig konstruierten Objekte enthalten.
Gibt es eine Möglichkeit, dass sich die Klassen aufeinander beziehen oder haben? keine andere Wahl, als alle meine Methoden in eine einzige Klasse zu übertragen?
Meiner Meinung nach sind zyklische Referenzen ein Code-Geruch. Siehe diese Antwort für eine Erklärung. Beachten Sie besonders den Punkt über cognitive load
.
Die Lösung besteht darin, eine Klasse von der anderen abhängig zu machen und die Aufrufe an die andere Klasse zu delegieren:
%Vor% Auf diese Weise übertragen Sie nicht wirklich alle Methoden auf eine Klasse, sondern komponieren nur class2
in class1
. Andere Klassen, die von class1
und class2
abhängig sind, müssen nur von class1
abhängen.
Was tatsächlich passiert, ist, dass Sie eine Instanz von Class1
im Konstruktor erstellen,
Class2
im Konstruktor,
Class1
im Konstruktor,
Class2
im Konstruktor,
Ihre Konstruktoren erstellen rekursiv Instanzen, wodurch der Call-Stack überflutet wird, was zu einem StackOverflowError
führt.
Ich nehme an, Sie möchten, dass eine Instanz von Class1
einen Verweis auf eine Instanz von Class2
enthält und umgekehrt?
In diesem Fall können Sie das einfach tun:
%Vor%Zyklische Aggregationen wie diese sind oft ein Zeichen für ein schlechtes Design; aber es sind Situationen, in denen es absolut gültig ist oder zumindest die Realität widerspiegelt.