Was sind die Symptome in einer Codebasis, die darauf hinweisen, dass ein Ereignis-Listener-Ansatz erforderlich ist?
Es scheint mir, dass wenn es Klassen gibt, die von mehreren aufgerufen werden müssen, die nicht zur Entwurfszeit anderer Klassen definiert sind, Sie eine Art Signalisierungsrahmen benötigen, aber ich würde gerne hören, welche anderen Situationen es gibt verbessert durch den Wechsel zu einem ereignisbasierten Modell.
quelle
Wenn Sie nicht wissen können oder sollten, was auf eine Reihe von Nachrichten / Signalen / Ereignissen reagieren soll.
Oft ist es, wenn Sie möchten, dass "die Welt" etwas über etwas erfährt, das in einem Modul passiert (eine Klasse oder ein Klassensystem), aber Sie möchten sich nicht darum kümmern, was genannt wird.
Der damit verbundene Code-Geruch ist, um genau zu sein, wenn Sie das Gefühl haben, Code aus unabhängigen Modulen zu mischen, wobei eines etwas tut, auf das das andere reagieren sollte. Sobald Sie sehen, dass Sie abhängig vom Status / den Ereignissen von Modul A Code aus Modul B aufrufen müssen, benötigen Sie Ereignis-Listener.
quelle
Ich würde Ihre Frage ändern und sagen: Wenn eine ereignisbasierte nicht die richtige Lösung für eine objektorientierte Anwendung ist? Ich denke, dass die meisten OO-Anwendungen davon profitieren können, wenn sie als Event-Produzenten und -Konsumenten konzipiert sind.
Am Ende ist ein "Methodenaufruf" tatsächlich eine Nachricht, die an einem Objekt ankommt, und das Objekt ist dafür verantwortlich, zu entscheiden, ob es etwas mit der Nachricht zu tun hat, und die Operation auszuführen. Dies ist in stark typisierten Sprachen wie Java nicht sehr klar, wird jedoch in dynamischen Sprachen wie Ruby deutlicher.
Ein weiterer interessanter Punkt beim Entwerfen einer Anwendung als ereignisbasiert ist, dass die internen Komponenten normalerweise ordnungsgemäß isoliert und kohärent sein müssen, da sonst der Code sehr, sehr schnell zu einem Chaos wird. Als Beispiel gefällt mir das von Alistair Cockburn verwendete Konzept der hexagonalen Architektur sehr gut , da dieses Muster normalerweise eine bessere Verkapselung erzeugt und (meiner Ansicht nach) kohäsivere Komponenten erzwingt.
Ich denke (aber ich liege wahrscheinlich falsch), dass dies auch mit dem Domain Driven Design-Konzept von Domain-Ereignissen zusammenhängt , bei dem die Domain-Klassen Ereignisse ausgeben, die von anderen Objekten erfasst werden, und diese Objekte noch andere Ereignisse ausgeben (Sie sehen, wo das geht: D). Was mir an diesem Muster gefällt, ist, dass Schnittstellen Rollen modellieren sollten, keine Implementierungen.
Es tut mir leid, wenn ich nicht viel Sinn mache. Ich habe in den letzten Monaten mit diesen Mustern experimentiert und dabei erstaunliche Ergebnisse erzielt, aber ich versuche immer noch, die Konzepte zu verstehen und zu verstehen, wie weit sie reichen.
quelle
Überlegen Sie, was Sie tun müssten, wenn Event-Listener (auch bekannt als Observer Pattern) nicht vorhanden wären.
Wenn Sie ein Objekt haben, das Verweise auf eine Liste anderer Objekte enthält und zu einem bestimmten Zeitpunkt im Prozess eine Methode aufruft, sollten Sie dort definitiv ein Ereignis gehabt haben.
Wenn Sie ein Flag auf einem Objekt haben, das angibt, dass etwas getan wurde, und Sie dieses Flag von anderen Objekten aus beobachten, sollten Sie auf jeden Fall ein ereignisgesteuertes Modell verwenden.
Verwechseln Sie dies jedoch nicht mit einem Rückruf. Wenn Sie eine Methode für ein anderes Objekt aufrufen und eine Methode für das Ursprungsobjekt übergeben, zu dem Sie zu einem bestimmten Zeitpunkt zurückrufen möchten, sollten Sie dies so lassen, anstatt einen Ereignis-Listener zu verwenden.
quelle