Zum Inhalt springen

Aufgabe 11 - Jahresprojekt Sprint 3 - Verhaltensmuster

Zu Zen-Modus wechseln
  • Du ordnest Verhaltensprobleme mit den Kernfragen aus Kapitel 17 Observer, Strategy, Command oder keinem Muster zu.
  • Du implementierst einen typisierten Observer mit Abmeldefunktion und sicherer Benachrichtigung.
  • Du setzt in deinem Jahresprojekt ein Verhaltensmuster für eine echte Story bewusst ein.
  • Du dokumentierst die Entscheidung mit Problem, Grund und Alternative und mit einem UML-Diagramm.

Zweite Woche von Sprint 3. Kapitel 17 stellt drei Verhaltensmuster vor, die alle Verhalten in Objekte stecken, aber aus verschiedenen Gründen: Observer (mehrere reagieren auf ein Ereignis, ohne dass der Sender sie kennt), Strategy (ein austauschbares Verfahren) und Command (eine Aktion als Objekt, zum Beispiel für Undo). Kapitel 21 verlangt für das Jahresprojekt mindestens ein bewusst eingesetztes und dokumentiertes Muster. Heute setzt ihr es ein, und zwar dort, wo eine Story es braucht, nicht dort, wo es hübsch aussieht.

Die Kata, Teil 1: Welches Muster?

  1. Ein Upload-Dienst soll nach jedem fertigen Upload eine Vorschau erzeugen, einen Eintrag ins Protokoll schreiben und die Statistik erhöhen. Morgen kommt vielleicht eine Benachrichtigung dazu.
  2. Eine Bildbearbeitung hat „Rückgängig“ für Zuschneiden, Drehen und Filter.
  3. Eine Navigations-App berechnet die Route wahlweise als schnellste, kürzeste oder mautfreie; die Nutzerin wählt vor dem Start.
  4. Ein Formular zeigt nach dem Absenden eine einzige Erfolgsmeldung an.
  5. Eine Druckerei-App legt Aufträge in eine Warteschlange, die später nacheinander abgearbeitet wird.

Die Kata, Teil 2: Ein typisierter Event-Emitter in einer Datei emitter.ts, ausführbar mit npx tsx.

Dafür brauchst du:

  • Kapitel 17 Entwurfsmuster II – Verhalten (Observer mit Abmeldung und Memory Leak, Strategy, Command mit undo, Tabelle und Entscheidungsbaum „Welches Muster für welches Problem?“, Einsatz im Jahresprojekt).
  • Die Musterkandidaten im Design-Review aus Aufgabe 07 und eure Stories von Sprint 3.

Projektordner anlegen siehe https://qiz.at/projektordner

  • Lies vorher kurz https://qiz.at/assignmentsabgabe durch.
  • Nur vollständige Abgaben (siehe https://qiz.at/rules) können positiv bewertet werden.
  • Abgabe- und Testdetails siehe https://qiz.at/assignmentsabgabe
  • Abgegeben wird dein Projektordner mit der Kata (Code und README.md) und den Links auf Issues, Merge Requests und Abschnitte im docs/design-review.md des Jahresprojekts. Bezeichner und Kommentare im Code sind Englisch.
  • Wer was beigetragen hat, zeigen Board, Merge Requests und /spend-Einträge (Kapitel 07).
  • Kata, Teil 1: Ordne die fünf Situationen Observer, Strategy, Command oder „kein Verhaltensmuster nötig“ zu. Gehe dafür die Fragen des Entscheidungsbaums der Reihe nach durch und begründe jede Wahl in einem Satz mit der Kernfrage des Musters.
  • Kata, Teil 2: Implementiere EventEmitter<T> ohne any: subscribe(listener) gibt eine Funktion zurück, die genau diese Anmeldung entfernt, emit(event) benachrichtigt alle Listener. Meldet sich ein Listener während emit ab, dürfen die übrigen dieser Runde nicht ausfallen. Prüfe das mit einem Test, in dem der abmeldende Listener vor einem zweiten angemeldet ist.

Tipp: emit arbeitet mit einer Kopie der Listener-Liste. Der Test beweist nur etwas, wenn der abmeldende Listener vorne hängt.

Vollständig, wenn:

  • alle fünf Situationen richtig zugeordnet sind (Observer, Command, Strategy, kein Muster, Command) und jede Begründung die Kernfrage nennt,
  • EventEmitter<T> generisch ohne any ist, subscribe eine Abmeldefunktion liefert und der Test zur Abmeldung während emit grün ist und die Reihenfolge prüft.

Wie unter Allgemein.

Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.

Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieser Datei (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):

  • Wählt eine Story aus Sprint 3 (oder einen Musterkandidaten aus der Kategorie Verhalten), bei der eines der drei Muster ein echtes Problem löst. Wendet den Entscheidungsbaum an und haltet das Ergebnis fest.
  • Setzt das Muster in einem Merge Request um, so klein wie möglich: bei Observer ein Subject, das seine Beobachter nicht kennt, bei Strategy ein Interface mit austauschbaren Verfahren, bei Command Kommandos mit execute und undo und eine Historie, die keine Fachlogik kennt. Ein Test zeigt das Verhalten, das das Muster ermöglicht.
  • Dokumentiert den Einsatz im Design-Review mit den drei Fragen aus Kapitel 17 (je ein Satz: Welches Problem lag vor? Warum dieses Muster? Was wäre die Alternative gewesen?), einem Muster-Steckbrief und einem Klassen- oder Sequenzdiagramm. Markiert die Stelle im Code mit einem kurzen Kommentar, der auf den Steckbrief verweist.

Tipp: Passt keines der drei Muster zu einer Story, ist das ein Ergebnis: Dokumentiert den Verzicht im Steckbrief und wählt eine andere Story. Ein Muster ohne Problem ist Patternitis, und die ist im Jahresprojekt ausdrücklich unerwünscht.

Vollständig, wenn:

  • die Wahl des Musters mit dem Entscheidungsbaum an einer echten Story begründet ist,
  • das Muster im Merge Request umgesetzt ist, die Rollen des Musters im Code nachweisbar sind und ein Test das ermöglichte Verhalten zeigt,
  • die drei Fragen, der Steckbrief und ein Diagramm im Design-Review stehen und die Code-Stelle markiert ist.

Wie unter Allgemein.

Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.

Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieser Datei (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):

  • Sichert euer Muster gegen seinen typischen Fehler ab, mit einem Test:
    • Observer: Jeder Beobachter wird wieder abgemeldet, wenn er verschwindet, zum Beispiel eine React-Komponente in der Aufräumfunktion von useEffect. Erkläre im Design-Review, wie ohne Abmeldung ein Memory Leak entsteht.
    • Strategy: Dieselbe aufrufende Klasse liefert nach einem Tausch der Strategie zur Laufzeit ein anderes Ergebnis, ohne eine konkrete Strategie zu kennen.
    • Command: undo stellt den vollständigen vorherigen Zustand her, auch nach mehreren Schritten, und ein Kommando, das scheitert, landet nicht in der Historie.
  • Füge eine zweite Variante (zweiter Beobachter, zweite Strategie, zweites Kommando) hinzu und weise mit git diff --stat nach, dass der auslösende bzw. aufrufende Code dafür unverändert blieb.

Tipp: Trenne beim Nachweis, was sich ändern darf (die Stelle, an der angemeldet oder ausgewählt wird), von dem, was sich nicht ändern darf.

Vollständig, wenn:

  • der Test den typischen Fehler des gewählten Musters abdeckt und grün ist,
  • die zweite Variante ohne Änderung am auslösenden bzw. aufrufenden Code hinzugekommen ist und der Diff das zeigt.

Wie unter Allgemein.

Für alle, die in der Einheit mit den Schritten oben fertig sind bzw. optional (= freiwillig), wenn du in der Einheit nicht fertig wirst.

Erweitere (siehe Erweitern in https://qiz.at/rules) den vollständigen Teil der vorherigen Stufe dieser Datei (ändere oder lösche nur, was für diese Aufgabe unbedingt notwendig ist):

  • Prüft eine zweite Stelle eures Projekts, an der eines der beiden anderen Verhaltensmuster in Frage kommt. Setzt es um oder dokumentiert den Verzicht, jeweils mit Steckbrief.
  • Grenze im Design-Review in vier bis sechs Sätzen die beiden Muster eures Projekts über ihren Zweck voneinander ab, nicht über die Klassenstruktur: Welche Kernfrage beantwortet jedes, und an welchem Erkennungszeichen würde ein neues Teammitglied es in eurem Code finden?

Tipp: Strategy und Command sehen im Klassendiagramm fast gleich aus (ein Interface, mehrere Implementierungen, ein Objekt, das sie hält). Eine Abgrenzung über die Struktur trägt deshalb nicht.

Vollständig, wenn:

  • die zweite Stelle mit Steckbrief umgesetzt oder begründet verworfen ist,
  • die Abgrenzung beide Kernfragen nennt und je ein im eigenen Code prüfbares Erkennungszeichen angibt.

Wie unter Allgemein.

Durchschnittlich bis Wesentlich_vollständig: ca. 70 min (5 min Board-Check, 25 min Kata, 40 min Muster im Projekt)

GAM

CC-BY-SA

https://qiz.at/rules