Wie können Sie zirkuläre Abhängigkeiten vermeiden, wenn Sie zwei Klassen mit einer Erzeuger/Verbraucher-Beziehung entwerfen? Hier benötigt ListenerImpl einen Verweis auf den Broadcaster, um sich selbst zu registrieren oder die Registrierung aufzuheben, und Broadcaster benötigt eine Referenz zurück zu den Listenern, um Nachrichten zu senden. Dieses Beispiel ist in Java, kann aber auf jede OO-Sprache angewendet werden.Wie können zirkuläre Abhängigkeiten vermieden werden, wenn Callbacks verwendet werden?
public interface Listener {
void callBack(Object arg);
}
public class ListenerImpl implements Listener {
public ListenerImpl(Broadcaster b) { b.register(this); }
public void callBack(Object arg) { ... }
public void shutDown() { b.unregister(this); }
}
public class Broadcaster {
private final List listeners = new ArrayList();
public void register(Listener lis) { listeners.add(lis); }
public void unregister(Listener lis) {listeners.remove(lis); }
public void broadcast(Object arg) { for (Listener lis : listeners) { lis.callBack(arg); } }
}
Aber es ist immer noch ein Referenzzyklus - Broadcaster hat einen Verweis zu dem konkreten ListenerImpl-Objekt, obwohl der Typ der Referenz der Listener-Schnittstellentyp ist. Bedeutet ein Referenzzyklus keinen Abhängigkeitszyklus? –
Es gibt keine Möglichkeit, einen Referenzzyklus zu entfernen. Es ist irgendwie für diese Art von Sache erforderlich. Referenzzyklen sind heutzutage nicht wirklich ein Problem, da jeder gute Garbage Collector sie gut behandeln sollte. Es sind die Abhängigkeitszyklen, über die Sie sich Sorgen machen müssen. – Herms
@sk: Um 'Zyklus' zu definieren, müssen Sie zuerst 'Abhängigkeit' definieren: Es gibt keinen Zyklus für die Kompilierung. Es ist ein Laufzeitzyklus, wenn alle Referenzen gleich sind und jemand den Zyklus unterbrechen muss, wenn er nicht mehr benötigt wird (Listener entfernen) – xtofl