Back to Course

Spot the Tax · Card 7 of 20

Adding a variant shouldn't mean editing every file

Why a case statement on notification.kind ends up scattered across half your codebase.

The code

What will this cost you in six months?

class NotificationDispatcher
  def deliver(notification)
    case notification.kind
    when "email"
      Mailer.with(to: notification.recipient).send_now
    when "sms"
      Twilio.send(notification.recipient, notification.body)
    when "push"
      Firebase.push(notification.device_token, notification.body)
    end
  end
end

The problem

The case statement on notification.kind lives here, but it almost never lives here only. The same case tends to show up in the delivery report, the analytics CSV export, the user's notification settings page, and probably the per-channel error handler too — anywhere in the app that needs to act differently depending on the kind. So when the team decides to add Slack as a fourth channel, you have to track down every one of those files and add a new when "slack" branch. Miss one, and that channel quietly misbehaves in that part of the app.

Take a moment. Before revealing, think about how you'd let new notification kinds be added without having to edit the dispatcher (and the report, and the settings page) every time.