Guided Exercise: Enterprise Notification System 📨 #103
Replies: 4 comments
-
|
PRASETHA N package com.edureka.practice.abstraction;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
abstract class Notification {
protected final String notificationId;
protected final String recipient;
protected final LocalDateTime createdAt;
protected String messageContent;
public Notification(String recipient, String messageContent) {
if (recipient == null || recipient.isEmpty() || messageContent == null || messageContent.isEmpty()) {
throw new IllegalArgumentException("Recipient or message content can not be empty");
}
this.notificationId = UUID.randomUUID().toString();
this.createdAt = LocalDateTime.now();
this.messageContent = messageContent;
this.recipient = recipient;
System.out.println("Notification constructor: ID " + this.notificationId + "created for " + this.recipient);
}
public abstract boolean send();
public String getNotificationMetadata() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return String.format("ID: %s | To: %s | Created: %s", this.notificationId, this.recipient,
this.createdAt.format(dtf));
}
public String getRecipient() {
return recipient;
}
public String getMessageContent() {
return messageContent;
}
public String getNotificationId() {
return notificationId;
}
}package com.edureka.practice.abstraction;
class AppNotification extends Notification {
private String targetDeviceId;
private String notificationTitle;
public AppNotification(String recipientUserId, String notificationTitle, String messageContent,
String targetDeviceId) {
super(recipientUserId, messageContent);
if (targetDeviceId == null || targetDeviceId.isEmpty() || notificationTitle == null
|| notificationTitle.isEmpty()) {
throw new IllegalArgumentException("targetDeviceId or notificationTitle content can not be empty");
}
this.notificationTitle = notificationTitle;
this.targetDeviceId = targetDeviceId;
System.out.println("AppNotification constructor for user " + recipientUserId); // For tracing
}
@Override
public boolean send() {
System.out.printf("--- Sending App Push Notification ---\n");
System.out.printf("To User ID: %s (Device: %s)\n", getRecipient(), this.targetDeviceId);
System.out.printf("Title: %s\n", this.notificationTitle);
System.out.printf("Payload: %s\n", getMessageContent());
System.out.println("------------------------------------");
System.out.println(
"App Notification sent successfully to user " + getRecipient() + " with ID: " + getNotificationId());
return true;
}
@Override
public String getNotificationMetadata() {
return super.getNotificationMetadata()
+ String.format(" | Type: App | Title:%s | Device: %s", this.notificationTitle, this.targetDeviceId);
}
}package com.edureka.practice.abstraction;
class EmailNotification extends Notification {
private String subject;
private String senderEmail;
public EmailNotification(String recipient, String subject, String messageContent, String senderEmail) {
super(recipient, messageContent);
if (subject == null || subject.isEmpty() || senderEmail == null || senderEmail.isEmpty()) {
throw new IllegalArgumentException("Subject or senderEmail can not be empty");
}
this.subject = subject;
this.senderEmail = senderEmail;
System.out.println("EmailNotification constructor for " + recipient);
}
@Override
public boolean send() {
System.out.printf("--- Sending Email ---\n");
System.out.printf("From: %s\n", this.senderEmail);
System.out.printf("To: %s\n", getRecipient());
System.out.printf("Subject: %s\n", this.subject);
System.out.printf("Body: %s\n", getMessageContent());
System.out.println("----------------------");
System.out.println("Email sent successfully to " + getRecipient() + " with ID: " + getNotificationId());
return true;
}
@Override
public String getNotificationMetadata() {
return super.getNotificationMetadata() + String.format(" | Type: Email |Subject: %s", this.subject);
}
}package com.edureka.practice.abstraction;
public class SlackNotification extends Notification {
private String channel;
public SlackNotification(String recipient, String messageContent, String channel) {
super(recipient, messageContent);
if (channel == null || channel.isEmpty()) {
throw new IllegalArgumentException("Channel can not be empty");
}
this.channel = channel;
System.out.println("SlackNotification constructor for " + recipient);
}
@Override
public boolean send() {
System.out.println("Sending Slack message to: " + getRecipient());
System.out.println("Channel: #" + channel);
System.out.println("Message: " + getMessageContent());
return true;
}
@Override
public String getNotificationMetadata() {
return super.getNotificationMetadata() + String.format(" | Type: Slack | FromChannel: %s", this.channel);
}
}package com.edureka.practice.abstraction;
class SmsNotification extends Notification {
private String sourcePhoneNumber;
public SmsNotification(String recipient, String messageContent, String sourcePhoneNumber) {
super(recipient, messageContent);
if (sourcePhoneNumber == null || sourcePhoneNumber.isEmpty()) {
throw new IllegalArgumentException("sourcePhoneNumber can not be empty");
}
if (messageContent.length() > 160) {
System.out.println("Warning: SMS message content truncated for " + recipient);
super.messageContent = messageContent.substring(0, 160);
}
this.sourcePhoneNumber = sourcePhoneNumber;
System.out.println("SmsNotification constructor for " + recipient); // For tracing
}
@Override
public boolean send() {
System.out.printf("--- Sending SMS ---\n");
System.out.printf("From: %s\n", this.sourcePhoneNumber);
System.out.printf("To: %s\n", getRecipient());
System.out.printf("Message: %s\n", getMessageContent());
System.out.println("--------------------");
System.out.println("SMS sent successfully to " + getRecipient() + " with ID:" + getNotificationId());
return true;
}
@Override
public String getNotificationMetadata() {
return super.getNotificationMetadata() + String.format(" | Type: SMS | FromNum: %s", this.sourcePhoneNumber);
}
}package com.edureka.practice.abstraction;
import java.util.ArrayList;
import java.util.List;
public class NotificationService {
public static void main(String[] args) {
System.out.println("## Enterprise Notification Service Demo ##\n");
List<Notification> notificationQueue = new ArrayList<>();
try {
EmailNotification email1 = new EmailNotification("user1@example.com", "Important Update",
"Your account has been updated.", "noreply@jpmc.com");
SmsNotification sms1 = new SmsNotification("+919876543210", "OTP: 123456. Valid for 5 mins.",
"+12025550101");
AppNotification appPush1 = new AppNotification("user123", "New Feature Alert!",
"Check out our new amazing feature in the app.", "deviceTokenXYZ789");
EmailNotification email2 = new EmailNotification("user2@example.com", "Weekly Newsletter",
"Here is your weekly news update...", "newsletter@jpmc.com");
SlackNotification slack1 = new SlackNotification("u123", "Updates", "Daily News");
notificationQueue.add(email1);
notificationQueue.add(sms1);
notificationQueue.add(appPush1);
notificationQueue.add(email2);
notificationQueue.add(slack1);
} catch (IllegalArgumentException e) {
System.err.println("Error creating notification: " + e.getMessage());
}
System.out.println("\n--- Processing Notification Queue ---");
if (notificationQueue != null && !notificationQueue.isEmpty()) {
for (Notification notification : notificationQueue) {
System.out.println("\nProcessing notification: " + notification.getNotificationId());
System.out.println("Metadata: " + notification.getNotificationMetadata());
boolean success = notification.send();
if (success) {
System.out.println("Status: SENT");
} else {
System.out.println("Status: FAILED");
}
System.out.println("-----------------------------------");
}
} else {
System.out.println("Notification queue is empty or not initialized.");
}
System.out.println("\n## Notification processing complete. ##");
}
} |
Beta Was this translation helpful? Give feedback.
-
|
Lohith R package org.example; import java.time.LocalDateTime; abstract class Notification { } package org.example; class EmailNotification extends Notification { } package org.example; public class AppNotification extends Notification{ } package org.example; class SmsNotification extends Notification{ private String sourcePhoneNumber; } package org.example; import java.util.ArrayList; public class NotificationService { } |
Beta Was this translation helpful? Give feedback.
-
|
Task 1 - Sayan Dey |
Beta Was this translation helpful? Give feedback.
-
|
Naga Nandhini // NotificationService.java
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
/**
* Abstract base class for all notification types.
* Defines common properties and behaviors for notifications.
*
* @version 1.0
* @since 2025-05-23
*/
abstract class Notification {
protected final String notificationId;
protected final String recipient;
protected final LocalDateTime createdAt;
protected String messageContent;
/**
* Constructs a new Notification.
*
* @param recipient The recipient of the notification. Must not be null or empty.
* @param messageContent The core message content. Must not be null or empty.
* @throws IllegalArgumentException if recipient or messageContent is invalid.
*/
public Notification(String recipient, String messageContent) {
if (recipient == null || recipient.isBlank()) {
throw new IllegalArgumentException("Recipient cannot be null or blank.");
}
if (messageContent == null || messageContent.isBlank()) {
throw new IllegalArgumentException("Message content cannot be null or blank.");
}
this.notificationId = UUID.randomUUID().toString();
this.createdAt = LocalDateTime.now();
this.recipient = recipient;
this.messageContent = messageContent;
System.out.println("Notification constructor: ID " + this.notificationId + " created for " + this.recipient);
}
/**
* Sends the notification.
*
* @return true if sending was successful, false otherwise.
*/
public abstract boolean send();
/**
* Retrieves common metadata for the notification.
*
* @return A string containing common notification metadata.
*/
public String getNotificationMetadata() {
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
return String.format("ID: %s | To: %s | Created: %s",
this.notificationId,
this.recipient,
this.createdAt.format(dtf));
}
public String getRecipient() {
return recipient;
}
public String getMessageContent() {
return messageContent;
}
public String getNotificationId() {
return notificationId;
}
}
/**
* Represents an Email Notification.
*/
class EmailNotification extends Notification {
private String subject;
private String senderEmail;
public EmailNotification(String recipient, String subject, String messageContent, String senderEmail) {
super(recipient, messageContent);
if (subject == null || subject.isBlank()) {
throw new IllegalArgumentException("Email subject cannot be blank.");
}
if (senderEmail == null || senderEmail.isBlank()) {
throw new IllegalArgumentException("Sender email cannot be blank.");
}
this.subject = subject;
this.senderEmail = senderEmail;
System.out.println("EmailNotification constructor for " + recipient);
}
@Override
public boolean send() {
System.out.println("--- Sending Email ---");
System.out.println("From: " + this.senderEmail);
System.out.println("To: " + getRecipient());
System.out.println("Subject: " + this.subject);
System.out.println("Body: " + getMessageContent());
System.out.println("----------------------");
System.out.println("Email sent successfully to " + getRecipient() + " with ID: " + getNotificationId());
return true;
}
@Override
public String getNotificationMetadata() {
return super.getNotificationMetadata() + String.format(" | Type: Email | Subject: %s", this.subject);
}
}
/**
* Represents an SMS Notification.
*/
class SmsNotification extends Notification {
private String sourcePhoneNumber;
public SmsNotification(String recipient, String messageContent, String sourcePhoneNumber) {
super(recipient, messageContent.length() > 160 ? messageContent.substring(0, 160) : messageContent);
if (sourcePhoneNumber == null || sourcePhoneNumber.isBlank()) {
throw new IllegalArgumentException("Source phone number cannot be blank.");
}
this.sourcePhoneNumber = sourcePhoneNumber;
if (messageContent.length() > 160) {
System.out.println("Warning: SMS message content truncated for " + recipient);
}
System.out.println("SmsNotification constructor for " + recipient);
}
@Override
public boolean send() {
System.out.println("--- Sending SMS ---");
System.out.println("From: " + this.sourcePhoneNumber);
System.out.println("To: " + getRecipient());
System.out.println("Message: " + getMessageContent());
System.out.println("--------------------");
System.out.println("SMS sent successfully to " + getRecipient() + " with ID: " + getNotificationId());
return true;
}
@Override
public String getNotificationMetadata() {
return super.getNotificationMetadata() + String.format(" | Type: SMS | FromNum: %s", this.sourcePhoneNumber);
}
}
/**
* Represents an App Push Notification.
*/
class AppNotification extends Notification {
private String targetDeviceId;
private String notificationTitle;
public AppNotification(String recipientUserId, String notificationTitle, String messageContent, String targetDeviceId) {
super(recipientUserId, messageContent);
if (notificationTitle == null || notificationTitle.isBlank()) {
throw new IllegalArgumentException("Notification title cannot be blank.");
}
if (targetDeviceId == null || targetDeviceId.isBlank()) {
throw new IllegalArgumentException("Device ID cannot be blank.");
}
this.notificationTitle = notificationTitle;
this.targetDeviceId = targetDeviceId;
System.out.println("AppNotification constructor for user " + recipientUserId);
}
@Override
public boolean send() {
System.out.println("--- Sending App Push Notification ---");
System.out.println("To User ID: " + getRecipient() + " (Device: " + this.targetDeviceId + ")");
System.out.println("Title: " + this.notificationTitle);
System.out.println("Payload: " + getMessageContent());
System.out.println("------------------------------------");
System.out.println("App Notification sent successfully to user " + getRecipient() + " with ID: " + getNotificationId());
return true;
}
@Override
public String getNotificationMetadata() {
return super.getNotificationMetadata() + String.format(" | Type: App | Title: %s | Device: %s", this.notificationTitle, this.targetDeviceId);
}
}
/**
* Main class to test the notification system.
*/
public class NotificationService {
public static void main(String[] args) {
Notification email = new EmailNotification(
"user@example.com",
"Welcome",
"Thank you for joining our platform!",
"noreply@company.com"
);
Notification sms = new SmsNotification(
"9876543210",
"Your OTP is 123456. Do not share it with anyone.",
"TX-COMPANY"
);
Notification app = new AppNotification(
"user123",
"New Offer",
"You have unlocked a 20% discount!",
"device-token-abc123"
);
Notification[] notifications = { email, sms, app };
for (Notification n : notifications) {
System.out.println("\n" + n.getNotificationMetadata());
n.send();
}
}
} |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Exercise: Enterprise Notification System 📨
Objective: To design and implement a flexible notification system using core Java OOP principles, including inheritance, abstract classes, abstract methods, concrete methods in abstract classes, constructors, and dynamic polymorphism, adhering to enterprise coding standards.
Scenario:
Imagine you're building a core module for a large enterprise application (e.g., at JPMC). This module is responsible for sending various types of notifications to users: Email, SMS, and perhaps future types like Push Notifications or Slack messages. The system needs to be extensible to easily add new notification methods without significantly altering existing code. Each notification type shares some common properties (like a recipient and a creation timestamp) but has unique ways of being sent and formatted.
Core Requirements:
Notificationclass that is abstract. It will define common properties and behaviors.EmailNotification,SmsNotification,AppNotification) that inherit fromNotification.Instructions:
Create a single Java file named
NotificationService.java. This file will contain all the classes for this exercise.Step 1: Define the Abstract
NotificationClassRationale:
Notificationitself is a general concept. You don't send a "generic" notification; you send a specific type (Email, SMS). Hence,Notificationwill be abstract. It will contain:* Common properties.
* A constructor to initialize common properties.
* A concrete method useful for all notification types.
* An abstract method that must be implemented by all concrete notification types.
Industrial Use-Case Insight: Abstract classes like
Notificationare common in enterprise systems (e.g.,OrderProcessor,PaymentGateway,MessageHandler). They establish a contract and share common logic for a family of related components.Step 2: Create Concrete Notification Subclasses
These classes will extend
Notificationand provide specific implementations for thesend()method and any other type-specific behavior.2.1
EmailNotification2.2
SmsNotification2.3
AppNotification(Push Notification)Enterprise Grade Code Insight: Notice the constructors validating input. In real systems, you'd also have more robust error handling, logging (e.g., using Log4j or SLF4j), and potentially specific exceptions.
Step 3: Implement the
NotificationServiceDriver ClassThis class will contain the
mainmethod to demonstrate the creation and polymorphic processing of notifications.Dynamic Polymorphism Insight: The loop
for (Notification notification : notificationQueue)is key.notification.send()calls thesend()method specific to the actual runtime type of the object (Email, SMS, App), not just theNotificationreference type. This is the essence of dynamic polymorphism.Guide for Trainees:
Notification.java: Fill in theTODOsections. Understand why each part is designed the way it is (abstract class, abstract method, concrete method).EmailNotification,SmsNotification, andAppNotification. Pay attention to:super()in constructors.send()method with simulated logic.getNotificationMetadata()to add more specific info.NotificationService.java: Write themainmethod to:List<Notification>.send()andgetNotificationMetadata()on each. Observe the polymorphic behavior.Beta Was this translation helpful? Give feedback.
All reactions