Skip to main content

Design a Notification System

Problem Statement

Design a notification system that can send notifications to users through multiple channels such as email, SMS, and push notifications. The design should support different notification types while keeping the sending logic extensible and easy to maintain.


Functional Requirements

  • The design should support multiple notification channels
  • Users should be able to receive notifications through email, SMS, or push notifications
  • The system should allow sending custom notification messages
  • Each notification type should have its own sending logic
  • The design should be extensible for adding future notification channels
  • The system should separate notification creation from delivery logic

Objects Required

  • Notification
  • EmailNotification
  • SMSNotification
  • PushNotification
  • NotificationService
  • User

User Class

The User class stores recipient information required for notifications.


public class User {

    private String userId;
    private String name;
    private String email;
    private String phoneNumber;

    public User(String userId,
                String name,
                String email,
                String phoneNumber) {

        this.userId = userId;
        this.name = name;
        this.email = email;
        this.phoneNumber = phoneNumber;
    }

    public String getEmail() {
        return email;
    }

    public String getPhoneNumber() {
        return phoneNumber;
    }

    public String getName() {
        return name;
    }
}

The constructor initializes all user related details required for notification delivery.

The getter methods are used by notification classes while sending messages through different channels.


Notification Abstract Class

The Notification class acts as the base abstraction for all notification types.


public abstract class Notification {

    protected User user;
    protected String message;

    public Notification(User user,
                        String message) {

        this.user = user;
        this.message = message;
    }

    public abstract void send();
}

The constructor stores the recipient and notification message.

The send() method is declared abstract because every notification type has different delivery logic.

This design allows all notification channels to follow a common structure while implementing their own behavior.


EmailNotification Class

The EmailNotification class handles email based notifications.


public class EmailNotification
        extends Notification {

    public EmailNotification(User user,
                             String message) {

        super(user, message);
    }

    @Override
    public void send() {

        System.out.println(
                "Sending Email to "
                + user.getEmail()
                + " : "
                + message
        );
    }
}

The constructor delegates common initialization to the parent notification class.

The send() method contains logic specific to email delivery.


SMSNotification Class

The SMSNotification class handles SMS based notifications.


public class SMSNotification
        extends Notification {

    public SMSNotification(User user,
                           String message) {

        super(user, message);
    }

    @Override
    public void send() {

        System.out.println(
                "Sending SMS to "
                + user.getPhoneNumber()
                + " : "
                + message
        );
    }
}

The constructor initializes the notification using the parent class.

The send() method contains SMS specific delivery behavior.


PushNotification Class

The PushNotification class handles app push notifications.


public class PushNotification
        extends Notification {

    public PushNotification(User user,
                            String message) {

        super(user, message);
    }

    @Override
    public void send() {

        System.out.println(
                "Sending Push Notification to "
                + user.getName()
                + " : "
                + message
        );
    }
}

The send() method simulates push notification delivery to the user.

Each notification type overrides the same method differently, which keeps the design flexible.


NotificationService Class

The NotificationService class coordinates notification delivery.


public class NotificationService {

    public void sendNotification(
            Notification notification) {

        notification.send();
    }
}

The sendNotification() method accepts the parent Notification type instead of individual implementations.

This allows the service to work with email, SMS, push notifications, or any future notification type without modification.


Main Class

The Main class demonstrates how different notification channels are used.


public class Main {

    public static void main(String[] args) {

        User user = new User(
                "U1",
                "TheLazyCode",
                "LazyCoder@gmail.com",
                "0123456789"
        );

        NotificationService service =
                new NotificationService();

        Notification email =
                new EmailNotification(
                        user,
                        "Your order has been placed"
                );

        Notification sms =
                new SMSNotification(
                        user,
                        "Your OTP is 1234"
                );

        Notification push =
                new PushNotification(
                        user,
                        "New offers available"
                );

        service.sendNotification(email);

        service.sendNotification(sms);

        service.sendNotification(push);
    }
}

The main() method starts by creating a user object.

Different notification objects are then created using the same base notification abstraction.

The notification service sends all notifications through a common interface.

This demonstrates how polymorphism simplifies handling multiple notification channels.


Class Diagram

Notificationuser : Usermessage : Stringsend() : voidUseruserId : Stringname : Stringemail : StringphoneNumber : StringgetEmail() : StringgetPhoneNumber() : StringgetName() : StringEmailNotificationsend() : voidSMSNotificationsend() : voidPushNotificationsend() : voidNotificationServicenotification : NotificationsendNotification() : voidMainmain(args : String[]) : void

Also See

Comments

Popular posts from this blog

Designing a Parking Lot - Low Level Design

Problem Statement Design a parking lot that can handle vehicles entering and leaving while managing parking across multiple floors. Each vehicle should be assigned a suitable parking spot based on its type, and the spot should be freed once the vehicle exits. The design should also support generating a ticket at entry and optionally calculating the parking fee based on the duration of stay. Asked In Companies Amazon Google Microsoft Uber Walmart Flipkart Meta PayPal Oracle Salesforce Adobe Apple Intuit LinkedIn Atlassian Functional Requirements The design should support multiple vehicle types such as bikes, cars, and trucks A vehicle must be assigned a parking spot compatible with its type A parking spot cannot be assigned to more than one vehicle at a time The parking lot should support multiple levels (floors) The design should search and allocate an availa...

Most Frequently Asked Low Level Design(LLD) Interview Questions

Below are the curated list of most commonly asked Low Level Design (LLD) interview problems. Each problem includes a short description and a link to the complete solution with code and class diagrams. Design Parking Lot System The system should handle parking for different vehicle types such as bikes, cars, and trucks. It should manage slot allocation, availability tracking, and entry/exit flow. The design also ensures efficient usage of parking space under varying load conditions. View Solution Design Elevator / Lift System The system should support multiple elevators operating across floors with request handling logic. It focuses on scheduling algorithms to minimize wait time and optimize movement. It also manages direction control and concurrent floor requests. View Solution Design Movie Ticket Booking System The system should allow users to browse movies, select shows, and book seats. It handles seat ...

Software Design Patterns for LLD Interviews: A Complete Guide

Software Design Patterns for LLD Interviews: A Complete Guide In Software Development Engineer (SDE) interviews—especially for mid-level and senior roles—low-level design (LLD) rounds assess your ability to write clean, reusable, maintainable, and extensible code. The foundation of resolving these architectural challenges lies in the standard Gang of Four (GoF) Design Patterns. Rather than memorizing theoretical definitions, interviewers expect you to apply these patterns to real-world scenarios, identifying the trade-offs of each. Below is a comprehensive guide to the 12 most frequently asked design patterns in LLD interviews, categorized by their classification (Creational, Structural, and Behavioral). Each pattern contains a concrete, real-world Java implementation and a detailed breakdown of design decisions. Creational Design Patterns Creational design patterns deal with object creation mechanisms. They abstract the instantiation process, making a system independent of how...