Unendliche Schleifen können nur passieren, wenn (a) Beobachter auch beobachtbar sind, (b) Veränderungen, die sie beobachten, zu Veränderungen in sich führen können, (c) der Beobachtungsgraph zyklisch ist und (d) eine Art von Änderung vorliegt was zu einer gleichartigen Veränderung führen kann. Die ideale Lösung bestünde darin, das Risiko von Endlosschleifen auszugleichen, indem sichergestellt wird, dass eine dieser Anforderungen fehlt. Wenn Ihr aktuelles Design alle vier wahr macht, sehen Sie, ob Sie es ändern können, um einen von ihnen falsch zu machen.
Die traditionellen Verwendungen für Observer-Observable sind in geschichteten Architekturen - zum Beispiel, wo View-Controller Modellobjekte beobachten oder Event-Handler GUI-Komponenten beobachten - und hier ist das Diagramm nicht zyklisch, so dass kein Risiko besteht Endlosschleife.
Ich sollte wahrscheinlich über Punkt (d), über verschiedene Arten von Änderungen erklären. Was ich meine ist, dass, wenn Sie eine Situation haben, wo ein UserInputEvent ein ModelStateChangedEvent auslösen kann und ein ModelStateChangedEvent ein WidgetUpdateEvent auslösen kann, das selbst nichts auslösen kann, selbst wenn die Beobachter einen zyklischen Graphen bilden, können Sie niemals Erhalten Sie unendliche Schleifen, weil es nur eine endliche Anzahl von Stufen in der Abfolge von Ereignissen gibt. Effektiv bilden die Ereignisse einen azyklischen Graphen, selbst wenn die Beobachter dies nicht tun. Wenn jedoch ein ModelStateChangedEvent ein anderes ModelStateChangedEvent auslösen kann, besteht die Gefahr von Zyklen.
Wenn Sie wirklich nicht das Risiko von Zyklen vermeiden können, dann können Sie eine Idee aus Jon Postel stehlen, und jede Ereignisbenachrichtigung eine ganzzahlige Time-to-live-Zähler führen. Wenn ein Observable ein "originelles" Ereignis ausstrahlt, was etwas bedeutet, das von außerhalb des Beobachter-Netzwerks kommt und eine Kaskade von Ereignissen in ihm auslöst, setzt es den Zähler auf einen geeigneten anfänglichen TTL-Wert. Wenn ein Observable auf ein Ereignis reagiert, indem er ein anderes Ereignis ausstrahlt, würde es eine TTL weniger als die des auslösenden Ereignisses verwenden. Wenn ein Beobachter eine Benachrichtigung mit einer TTL von Null erhält, ignoriert er dies.Dies würde unendliche Schleifen verhindern, würde aber auch verhindern, dass ein Beobachter auf einige Ereignisse "richtig" reagiert, also ist es eine Idee, mit Vorsicht verwendet zu werden. Ich würde sehr empfehlen, dass eine Ereigniskaskade, die das TTL-Limit erreicht, als das Ergebnis eines Programmierfehlers betrachtet wird und auf die gleiche Weise protokolliert und gemeldet werden sollte, wie Sie mit einer NullPointerException oder einem Assertionsfehler umgehen.
Arrr, Leiter der ersten Entwurfsmuster. Ganz oben in der Liste der Bücher mit den dümmsten Titelbildern. –