Real alerts rarely target one channel, an outage should hit email and SMS and push at once. Because every notifier shares the same send shape and the factory builds any of them on demand, fan-out is a short loop over the single-channel path you already have.
Add broadcast to NotificationService:
Reuse notify from Step 4 rather than re-deriving it. An empty channel list should return an empty list.
class Notifier:
def send(self, message):
raise NotImplementedError
class EmailNotifier(Notifier):
def send(self, message):
return {"channel": "email", "message": message}
class SmsNotifier(Notifier):
def send(self, message):
return {"channel": "sms", "message": message}
class PushNotifier(Notifier):
def send(self, message):
return {"channel": "push", "message": message}
def notifier_for(channel):
if channel == "email":
return EmailNotifier()
if channel == "sms":
return SmsNotifier()
if channel == "push":
return PushNotifier()
raise ValueError("unknown channel: " + str(channel))
class NotifierFactory:
def __init__(self):
self._registry = {}
def register(self, channel, cls):
self._registry[channel] = cls
def create(self, channel):
if channel not in self._registry:
raise ValueError("unknown channel: " + str(channel))
return self._registry[channel]()
class NotificationService:
def __init__(self, factory):
self._factory = factory
def notify(self, channel, message):
notifier = self._factory.create(channel)
return notifier.send(message)
def broadcast(self, channels, message):
"""Send message on each channel; return the list of send results."""
# TODO: return [self.notify(c, message) for c in channels]
pass
The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.
Real alerts rarely target one channel, an outage should hit email and SMS and push at once. Because every notifier shares the same send shape and the factory builds any of them on demand, fan-out is a short loop over the single-channel path you already have.
Add broadcast to NotificationService:
Reuse notify from Step 4 rather than re-deriving it. An empty channel list should return an empty list.
Press Run Tests or ββ© to check your solution.