A notification system speaks many channels, email, SMS, push, but every channel answers the same question: given a message, deliver it and report what happened. That shared shape is an interface. Here it is the Notifier base class, whose send raises NotImplementedError so subclasses are forced to define real behavior.
Start with two concrete notifiers. Each send takes a message and returns a small delivery record: a dict with a channel key naming the channel and a message key carrying the text through unchanged.
Keeping the return shape identical across channels is what will later let a single caller treat any notifier the same way.
class Notifier:
def send(self, message):
raise NotImplementedError
class EmailNotifier(Notifier):
def send(self, message):
"""Return the delivery record for an email."""
# TODO: return {"channel": "email", "message": message}
pass
class SmsNotifier(Notifier):
def send(self, message):
"""Return the delivery record for an SMS."""
# TODO: return {"channel": "sms", "message": message}
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
A notification system speaks many channels, email, SMS, push, but every channel answers the same question: given a message, deliver it and report what happened. That shared shape is an interface. Here it is the Notifier base class, whose send raises NotImplementedError so subclasses are forced to define real behavior.
Start with two concrete notifiers. Each send takes a message and returns a small delivery record: a dict with a channel key naming the channel and a message key carrying the text through unchanged.
Keeping the return shape identical across channels is what will later let a single caller treat any notifier the same way.
Press Run Tests or ββ© to check your solution.