[copy constructor] Zirkulaer wechselseitig abhaengige Objekte kopieren
-
Zwei Objekte Foo und Bar stehen in einer 1:1 Aggregations Beziehung.
Foo <-> Barclass Foo { public Bar bar; public Foo(Foo f) { this.bar = f.bar; } } class Bar { public Foo foo; }
Es gilt die folgende Invariante fuer alle Objekte foo, bar:
foo.bar.foo == foo && bar.foo.bar == barIn Prosa: Beide Objekte referenzieren einander wechselseitig.
Jetzt will ich ein Foo Objekt kopieren.
public static void main(String[] args) { Foo foo0 = new Foo(); Bar bar = new Bar(); foo0.bar = bar; bar.foo = foo0; //everything is fine so far... //now construct a new Foo with the old foo0 Foo foo1 = new Foo(foo0); // foo1 ist jetzt korrupt! //Invariante ist verletzt foo1.bar.foo == foo0;
Ich habe gerade eine der haertesten debugging sessions hinter mir und inzwischen verstehe ich auch das Problem.
Der Copy constructor in Foo ist fehlerhaft.
Es fehlt die Zeilethis.bar.foo = this;
Als ich es bemerkte fiel es mir wie Schuppen von den Augen.
Diese Loesung ist aber ziemlich unschoen, da Foo nun in der internen Implementation von Bar herumfummeln muss - eine Klasse deren Innenleben Foo ueberhaupt nicht kennt/ kennen soll.
Wie stelle ich bei zirkulaeren Abhaengigkeiten wie dieser sicher, dass die Objekte nach dem Kopiervorgang noch konsistent sind, also aufeinander verweisen und nicht auf die alten Objekte?
Dies scheint mir ein sehr generelles Problem zu sein.
Hat jemand vll. einige Links zu Artikeln/Tutorials?thx in advance
-
gelöscht
-
Scheint mir ein Design-Fehler zu sein. Entweder man hat eine Beziehung wie Foo>Bar oder Bar>Foo. Wenn du aber wirklich Foo<>Bar hast, wieso hast du dann überhaupt 2 Klassen?
Hast du ein konkretes Beispiel, oder ist das einfach nur Theorie-Frage?
-
Seid wann sind bidirektionale Beziehung Design-Fehler?