Nach Lektion 2.14.2 bucht die Kladde über einen Anwendungsfall, und alle Benachrichtigungen stehen in einer Klasse, BookingNotifications. Diese Klasse hat einen Geruch, der in Lektion 2.14.1 schon auf der Liste stand: Drei Methoden, und in jeder ein switch über dieselben Kanäle. Jetzt will die Leitung einen vierten Kanal, ein Aktivitätsprotokoll, in dem sie nachlesen kann, was mit den Buchungen passiert ist. In dieser Lektion bauen Sie die Kanäle so um, dass ein neuer Kanal eine neue Datei ist, und keine der alten sich dafür ändert.

Der Geruch: dreimal derselbe switch

BookingNotifications aus Lektion 2.14.2 hat dreimal dieselbe Form:

C#
foreach (NotificationChannel channel in options.Value.Channels)
{
    switch (channel)
    {
        case NotificationChannel.Mail:
            …
        case NotificationChannel.Webhook:
            …
        case NotificationChannel.Live:
            …
    }
}

einmal in BookedAsync, einmal in ConfirmedAsync, einmal in CancelledAsync. Was müssen Sie für das Aktivitätsprotokoll tun?

  1. Die Aufzählung NotificationChannel um ActivityLog erweitern.
  2. In jedem der drei switch einen Fall ergänzen, und keinen vergessen. Der Compiler hilft dabei nicht: Ein switch-Statement ohne default über eine Aufzählung ist kein Fehler, wenn ein Fall fehlt.
  3. Den Konstruktor von BookingNotifications um die Abhängigkeit des Protokolls erweitern. Jeder Test, der die Klasse baut, muss sie jetzt liefern, auch die Tests für den Webhook.
  4. Den Charakterisierungstest und alle Tests von BookingNotifications erneut laufen lassen, denn jede ihrer Zeilen kann sich geändert haben.

Das ist der Schmerz: Eine neue Sache zwingt dazu, drei bewährte Stellen zu öffnen. Das O in SOLID, das Open-Closed-Prinzip, sagt: Ein Teil soll offen für Erweiterung und geschlossen für Änderung sein. Eine neue Art von Benachrichtigung soll hinzukommen können, ohne dass die Stellen, die heute funktionieren, angefasst werden.

Die Schnittstelle dafür gibt es schon: IBookingNotifier aus Lektion 2.14.2. Bisher hat sie eine Umsetzung, die alle Kanäle kennt. Nach dem Umbau hat sie eine Umsetzung je Kanal.