Before, notifications were sent directly inside business logic, mixing concerns and risking delays or failures. After applying the notification system pattern, notifications are queued and sent asynchronously respecting user preferences, improving reliability and scalability.
### Before: No notification system, direct calls
class OrderService:
def place_order(self, user, order):
# process order
self.send_email(user.email, "Order placed")
def send_email(self, email, message):
# direct email sending
print(f"Sending email to {email}: {message}")
### After: Using Notification System
from enum import Enum
class Channel(Enum):
EMAIL = 'email'
SMS = 'sms'
class Notification:
def __init__(self, user_id, message, channel):
self.user_id = user_id
self.message = message
self.channel = channel
class NotificationQueue:
def __init__(self):
self.queue = []
def enqueue(self, notification):
self.queue.append(notification)
def dequeue(self):
if self.queue:
return self.queue.pop(0)
return None
class NotificationService:
def __init__(self, queue, user_prefs):
self.queue = queue
self.user_prefs = user_prefs
def notify(self, user_id, message):
prefs = self.user_prefs.get(user_id, [Channel.EMAIL])
for channel in prefs:
notification = Notification(user_id, message, channel)
self.queue.enqueue(notification)
def process_notifications(self):
notification = self.queue.dequeue()
while notification:
self.send(notification)
notification = self.queue.dequeue()
def send(self, notification):
print(f"Sending {notification.channel.value} to user {notification.user_id}: {notification.message}")
class OrderService:
def __init__(self, notification_service):
self.notification_service = notification_service
def place_order(self, user_id, order):
# process order
self.notification_service.notify(user_id, "Your order has been placed.")
# Usage
user_prefs = {1: [Channel.EMAIL, Channel.SMS], 2: [Channel.EMAIL]}
queue = NotificationQueue()
notif_service = NotificationService(queue, user_prefs)
order_service = OrderService(notif_service)
order_service.place_order(1, "Order123")
notif_service.process_notifications()