// Core Notification System LLD in Java - Robust & Optimized import java.util.*; import java.util.concurrent.*; // Notification Service Interface interface NotificationService { void sendNotification(NotificationRequest request); } // Notification Channel Interface interface NotificationChannel { boolean send(NotificationMessage message); } // User Preference Service Interface interface UserPreferenceService { UserPreferences getPreferences(String userId); } // Data Classes class NotificationRequest { private String requestId; private String notificationType; private Map recipient; private List channels; private Map message; private ScheduleDetails schedule; private Map metadata; // Constructors, Getters, Setters omitted for brevity } class NotificationEvent { private String messageId; private String timestamp; private String notificationType; private String channel; private Map recipient; private Map messageContent; private Map metadata; // Constructors, Getters, Setters omitted for brevity } class NotificationMessage { private String messageId; private String channel; private Map recipient; private String content; // Constructors, Getters, Setters omitted for brevity } class UserPreferences { private String userId; private List preferredChannels; private Map optOutStatus; private Map rateLimits; // Constructors, Getters, Setters omitted for brevity } class ScheduleDetails { private Date scheduledTime; // Constructors, Getters, Setters omitted for brevity } // Concrete Implementations class NotificationServiceImpl implements NotificationService { private final BlockingQueue notificationQueue = new LinkedBlockingQueue<>(); private final UserPreferenceService userPreferenceService = new UserPreferenceServiceImpl(); private final SchedulerService schedulerService = new SchedulerService(); private final RateLimiterService rateLimiter = new RateLimiterService(); private final NotificationChannelFactory channelFactory = new NotificationChannelFactory(); private final RetryMechanism retryMechanism = new RetryMechanism(); @Override public void sendNotification(NotificationRequest request) { UserPreferences preferences = userPreferenceService.getPreferences(request.getRecipient().get("userId")); for (String channel : request.getChannels()) { if (!preferences.getPreferredChannels().contains(channel) || preferences.getOptOutStatus().getOrDefault(channel, false) || !RateLimiterService.allow(preferences.getUserId(), channel)) { continue; } NotificationEvent event = createEvent(request, channel); if (request.getSchedule() != null) { schedulerService.scheduleNotification(event); } else { notificationQueue.add(event); processEvent(event); } } } private NotificationEvent createEvent(NotificationRequest request, String channel) { // Event creation logic (populate fields) return new NotificationEvent(); } private void processEvent(NotificationEvent event) { NotificationMessage message = new NotificationMessage(); // populate NotificationChannel channel = channelFactory.getChannel(event.getChannel()); boolean success = channel.send(message); if (!success) { retryMechanism.retry(event); } } } // Channel Implementations class EmailNotificationChannel implements NotificationChannel { public boolean send(NotificationMessage message) { System.out.println("Email sent to: " + message.getRecipient()); return true; } } class SMSNotificationChannel implements NotificationChannel { public boolean send(NotificationMessage message) { System.out.println("SMS sent to: " + message.getRecipient()); return true; } } class PushNotificationChannel implements NotificationChannel { public boolean send(NotificationMessage message) { System.out.println("Push notification sent to: " + message.getRecipient()); return true; } } // Channel Factory for Dynamic Channel Retrieval class NotificationChannelFactory { private final Map channels = new HashMap<>(); public NotificationChannelFactory() { channels.put("EMAIL", new EmailNotificationChannel()); channels.put("SMS", new SMSNotificationChannel()); channels.put("PUSH", new PushNotificationChannel()); } public NotificationChannel getChannel(String channelType) { return channels.get(channelType); } } class UserPreferenceServiceImpl implements UserPreferenceService { public UserPreferences getPreferences(String userId) { // Fetch preferences from DB/cache (mocked here) return new UserPreferences(); } } class SchedulerService { public void scheduleNotification(NotificationEvent event) { System.out.println("Notification scheduled: " + event); } } class RateLimiterService { public boolean allow(String userId, String channel) { // Rate limiting logic (mocked true) return true; } } class RetryMechanism { public void retry(NotificationEvent event) { System.out.println("Retrying for event: " + event); // Implement retry logic here } } /* UML Diagram visit to visualize: https://www.planttext.com/ @startuml interface NotificationService { + sendNotification(request: NotificationRequest) } interface NotificationChannel { + send(message: NotificationMessage): boolean } interface UserPreferenceService { + getPreferences(userId: String): UserPreferences } class NotificationRequest { - requestId: String - notificationType: String - recipient: Map - channels: List - message: Map - schedule: ScheduleDetails - metadata: Map } class NotificationEvent { - messageId: String - timestamp: String - notificationType: String - channel: String - recipient: Map - messageContent: Map - metadata: Map } class NotificationMessage { - messageId: String - channel: String - recipient: Map - content: String } class UserPreferences { - userId: String - preferredChannels: List - optOutStatus: Map - rateLimits: Map } class ScheduleDetails { - scheduledTime: Date } class NotificationServiceImpl { + sendNotification(request: NotificationRequest) - createEvent(request: NotificationRequest, channel: String): NotificationEvent - processEvent(event: NotificationEvent) } class EmailNotificationChannel { + send(message: NotificationMessage): boolean } class SMSNotificationChannel { + send(message: NotificationMessage): boolean } class PushNotificationChannel { + send(message: NotificationMessage): boolean } class NotificationChannelFactory { + getChannel(channelType: String): NotificationChannel } class UserPreferenceServiceImpl { + getPreferences(userId: String): UserPreferences } class SchedulerService { + scheduleNotification(event: NotificationEvent) } class RateLimiterService { + allow(userId: String, channel: String): boolean } class RetryMechanism { + retry(event: NotificationEvent) } NotificationService <|-- NotificationServiceImpl NotificationServiceImpl --> NotificationRequest NotificationServiceImpl --> NotificationEvent NotificationServiceImpl --> NotificationChannelFactory NotificationServiceImpl --> UserPreferenceService NotificationServiceImpl --> SchedulerService NotificationServiceImpl --> RateLimiterService NotificationServiceImpl --> RetryMechanism NotificationChannel <|-- EmailNotificationChannel NotificationChannel <|-- SMSNotificationChannel NotificationChannel <|-- PushNotificationChannel NotificationChannelFactory --> NotificationChannel UserPreferenceService <|-- UserPreferenceServiceImpl UserPreferenceServiceImpl --> UserPreferences SchedulerService --> NotificationEvent RateLimiterService --> NotificationEvent RetryMechanism --> NotificationEvent @enduml */