Zum Inhalt springen

Aufgabe 05 - Factory im Einsatz

Zu Zen-Modus wechseln

Sie setzen Factory und Singleton in einem kleinen, realistischen Export-Szenario gezielt ein und erleben den Unterschied zwischen “Muster gelesen” und “Muster gebaut”. Am eigenen Code erfahren Sie, wie eine Factory das Open-Closed-Prinzip stützt und was ein Singleton im Test kostet (siehe Kapitel Entwurfsmuster I).

  • Kapitel Entwurfsmuster I (Factory, Registry, Singleton, Dependency Injection, Open-Closed).
  • Ein TypeScript-Projekt mit Testrunner (vitest); Ihr Vertragstest-Handwerk aus der 3. Klasse.
  • Sie implementieren eine Factory mit Interface und Registry und fügen Varianten ohne Änderung am Kern hinzu.
  • Sie bauen einen Singleton und weisen seine Testabhängigkeit praktisch nach.
  • Sie ersetzen globalen Zustand durch Dependency Injection und begründen die Abwägung.
  • Reproduktion: die naive switch-Lösung und ihre Kosten benennen (Teil A).
  • Reorganisation und Transfer: die Lösung als Factory umbauen und erweitern (Teile B und C).
  • Reflexion, Problemlösung und Urteilsbildung: globalen Zustand auflösen und die Muster-Wahl bewerten (Teil D).

Ihre Anwendung soll Berichte in verschiedenen Formaten exportieren: als Text, als CSV, als HTML - und nächste Woche bestimmt auch noch als Markdown.

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

Schreiben Sie die naive Version: eine Funktion exportReport(report, format) mit einem switch über das Format, die Logik inline. Sie funktioniert. Notieren Sie in zwei Sätzen, was beim Hinzufügen des vierten Formats alles angefasst werden muss, und gegen welches SOLID-Prinzip das verstößt.

  1. Interface Exporter (export(report): string, fileExtension), drei Implementierungen (Text, CSV, HTML).
  2. createExporter(format) liefert den passenden Exporter; ein unbekanntes Format ergibt einen aussagekräftigen Fehler (eigene Fehlerklasse).
  3. Tests, parametrisiert über alle Formate (Ihr Vertragstest-Handwerk).
  1. Ergänzen Sie den Markdown-Exporter ausschließlich mit neuen Zeilen. Zeigen Sie am Diff, dass der Aufrufer und die Factory-Kernlogik unangetastet bleiben.
  2. Der Export soll zählen, wie oft jedes Format verwendet wurde: ExportStatistics als Singleton.
  3. Schreiben Sie zwei Tests, die beide exportieren und die Statistik prüfen. Laufen sie unabhängig, egal in welcher Reihenfolge? Vermutlich nicht - der Singleton-Zustand klebt. Dokumentieren Sie das beobachtete Verhalten.

Teil D - Expertenteil: Registry und Dependency Injection

Abschnitt betitelt „Teil D - Expertenteil: Registry und Dependency Injection“
  1. Bauen Sie die Factory zur Registry um: eine Tabelle, in die sich Exporter eintragen. Ziel ist, dass ein neues Format null Änderungen an der Factory-Funktion braucht - nur eine Registrierungszeile. Weisen Sie das nach, indem Sie ein fünftes Format (etwa JSON) allein durch Registrierung hinzufügen.
  2. Lösen Sie das Singleton-Problem aus Teil C durch Dependency Injection: Die Statistik wird hereingereicht statt global geholt. Zeigen Sie an denselben zwei Tests, dass sie jetzt in beliebiger Reihenfolge grün sind, weil jeder Test eine frische Instanz bekommt.
  3. Abwägung in drei bis vier Sätzen: Wann war der Singleton bequem, was hat er im Test gekostet, und woran erkennt man, dass die injizierte Variante die robustere ist?
  1. Warum stützt eine Factory das Open-Closed-Prinzip?
  2. Was ist der Vorteil einer Registry gegenüber einem switch in der Factory?
  3. Warum überlebt der Zustand eines Singletons von einem Test in den nächsten, und warum ist das gefährlich?
  4. Wie beseitigt Dependency Injection genau dieses Problem?
  5. Was gewinnt der Aufrufer dadurch, dass er nur das Interface Exporter und keine konkrete Klasse kennt?

Git-Repository mit beiden Versionen (Teil A als erster Commit, damit die Historie den Weg zeigt), der Registry-Umbau, die injizierte Statistik, alle Tests grün und das Fazit aus Teil D.