Zum Inhalt springen

Aufgabe 06 - Observer selbst gebaut

Zu Zen-Modus wechseln

Sie bauen das Muster, das Sie seit der 1. Klasse benutzen, diesmal selbst: einen typisierten Event-Emitter, und setzen ihn in einem Live-Anzeige-Szenario ein. Der Kern ist die Entkopplung - der Sender kennt seine Empfänger nicht, und genau das macht das System erweiterbar (siehe Kapitel Entwurfsmuster II).

  • Kapitel Entwurfsmuster II (Observer mit An-/Abmeldung, Emit über eine Kopie der Liste).
  • Ein TypeScript-Projekt mit Testrunner; Generics aus der 4. Klasse.
  • Das Steckbrief-Format der Muster-Sammlung (aus Aufgabe 04).
  • Sie implementieren Subject und Observer mit Registrierung, Abmeldung und Benachrichtigung.
  • Sie typisieren Events mit Generics und halten den Sender frei von Wissen über die Empfänger.
  • Sie erkennen Observer in Frameworks wieder und benennen die Gefahr nicht abgemeldeter Beobachter.
  • Reproduktion: den Emitter nach dem Kapitelmuster bauen (Teil A).
  • Reorganisation und Transfer: ihn in ein entkoppeltes Szenario einsetzen und erweitern (Teil B).
  • Reflexion, Problemlösung und Urteilsbildung: das Muster in Frameworks wiedererkennen und einen typisierten Event-Bus entwerfen (Teile C und D).

Die Übung ist auf etwa zwei Stunden ausgelegt. Teil D ist der Expertenteil.

  1. Klasse EventEmitter<T> mit subscribe(listener): () => void (gibt die Abmeldefunktion zurück), der Abmeldung über eben diese Funktion, und emit(event: T).
  2. Tests: mehrere Listener erhalten das Event; abgemeldete nicht mehr; ein werfender Listener darf die anderen nicht verhindern (try/catch pro Listener - mit einem Kommentar, der begründet, warum).

Szenario Sporttag-Anzeige: Ein Competition-Objekt meldet Ereignisse (newTime, finish). Drei unabhängige Beobachter: Scoreboard (druckt formatiert), RecordWatcher (meldet nur, wenn eine Zeit den Bestwert unterbietet), Statistics (zählt und mittelt).

  1. Implementieren Sie das Szenario; Competition importiert keinen der drei Beobachter.
  2. Zeigen Sie die Entkopplung: Ergänzen Sie einen vierten Beobachter (LiveTicker, schreibt in eine Datei), ohne Competition anzufassen.
  3. Zeichnen Sie das UML: ein Klassendiagramm und eine Sequenz für eine einzelne Meldung.

Beantworten Sie schriftlich (je zwei bis drei Sätze):

  1. Wo genau ist addEventListener aus der 1. Klasse dieses Muster - wer ist Subject, wer Observer, was ist die Abmeldung?
  2. Warum ist Observer in GUI-Frameworks allgegenwärtig?
  3. Welche Gefahr entsteht, wenn Beobachter nie abbestellt werden (Stichwort aus der Praxis: Memory Leak)?
  1. Erweitern Sie den Emitter zu einem Event-Bus mit mehreren Ereignisarten: on(eventName, listener) und emit(eventName, payload), wobei der Payload-Typ vom Ereignisnamen abhängt (diskriminierte Union oder ein Event-Map-Typ). Der Compiler soll einen falschen Payload zum falschen Ereignis ablehnen.
  2. Weisen Sie die Iterations-Sicherheit nach: Schreiben Sie einen Test, in dem sich ein Listener während einer laufenden emit-Runde abmeldet, und zeigen Sie, dass die übrigen Listener korrekt bedient werden (Emit über eine Kopie der Liste).
  3. Beurteilen Sie in drei Sätzen: An welcher Stelle Ihres Jahresprojekts wäre ein solcher Event-Bus die richtige Entkopplung - und wo wäre er Overkill gegenüber einem direkten Funktionsaufruf?
  1. Warum gibt subscribe eine Abmeldefunktion zurück, statt den Listener zum späteren Entfernen zu verlangen?
  2. Warum iteriert emit über eine Kopie der Listener-Liste?
  3. Wer ist beim Observer das Subject und wer der Observer, und in welche Richtung fließt das Wissen (wer kennt wen)?
  4. Was ist die Kernfrage, an der man Observer von Strategy und Command unterscheidet?
  5. Wie entsteht durch nicht abgemeldete Beobachter ein Memory Leak?

Git-Repository mit Emitter, Szenario, Tests, UML und den Antworten aus Teil C; der typisierte Event-Bus aus Teil D; der Steckbrief “Observer” für die Muster-Sammlung.