After lesson 2.14.2, the Kladde books through a use case, and all notifications live in one class, BookingNotifications. That class has
a smell that was already on the list in lesson 2.14.1: three methods, and in each a switch over the same channels. Now management wants
a fourth channel, an activity log where it can read what happened to the bookings. In this lesson you rebuild the channels so that a new
channel is a new file, and none of the old ones changes for it.
The smell: the same switch three times
BookingNotifications from lesson 2.14.2 has the same shape three times:
foreach (NotificationChannel channel in options.Value.Channels)
{
switch (channel)
{
case NotificationChannel.Mail:
…
case NotificationChannel.Webhook:
…
case NotificationChannel.Live:
…
}
}
once in BookedAsync, once in ConfirmedAsync, once in CancelledAsync. What do you have to do for the activity log?
- Extend the
NotificationChannelenumeration withActivityLog. - Add a case in each of the three
switchstatements, and forget none. The compiler doesn’t help here: aswitchstatement withoutdefaultover an enumeration isn’t an error when a case is missing. - Extend the constructor of
BookingNotificationswith the log’s dependency. Every test that builds the class now has to supply it, the tests for the webhook too. - Run the characterization test and all the tests of
BookingNotificationsagain, because any of its lines may have changed.
That’s the pain: one new thing forces you to open three places that work. The O in SOLID, the open-closed principle, says: a part should be open for extension and closed for modification. A new kind of notification should be able to join without touching the places that work today.
The interface for that already exists: IBookingNotifier from lesson 2.14.2. So far it has one implementation that knows all the
channels. After the refactoring, it has one implementation per channel.