CCCPaste

Notification System LLD

// 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


*/