The design should allow adding new notification channels without modifying existing code, following the Open/Closed Principle.
Requirements
A notification system should meet the following requirements:1. Support multiple notification channels.
2. Send the same message through different channels.
3. Allow adding new channels with minimal code changes.
4. Keep channel implementations independent.
5. Support sending notifications to multiple recipients.
Design
A Notification interface defines the contract for sending notifications. Each notification channel implements this interface independently.A NotificationFactory creates the appropriate notification implementation. The client interacts only with the interface, making the implementation easily replaceable.

Java Implementation
The following implementation demonstrates the Factory Design Pattern, where a factory creates the appropriate notification object based on the requested notification type.Notification Interface
The Notification interface defines a common contract that all notification implementations must follow.public interface Notification {
void send(String recipient, String message);
}
Email Notification
This class implements the Notification interface and sends notifications through email.public class EmailNotification implements Notification {
@Override
public void send(String recipient, String message) {
System.out.println("Email sent to " + recipient + ": " + message);
}
}
SMS Notification
This class implements the Notification interface and sends notifications through SMS.public class SMSNotification implements Notification {
@Override
public void send(String recipient, String message) {
System.out.println("SMS sent to " + recipient + ": " + message);
}
}
Push Notification
This class implements the Notification interface and sends push notifications to users.public class PushNotification implements Notification {
@Override
public void send(String recipient, String message) {
System.out.println("Push notification to " + recipient + ": " + message);
}
}
Notification Type
This enum defines the supported notification types that clients can request.public enum NotificationType {
EMAIL,
SMS,
PUSH
}
Notification Factory
The NotificationFactory encapsulates object creation and returns the appropriate notification implementation based on the specified notification type.public class NotificationFactory {
public static Notification create(NotificationType type) {
return switch (type) {
case EMAIL -> new EmailNotification();
case SMS -> new SMSNotification();
case PUSH -> new PushNotification();
};
}
}
Notification Service
The NotificationService delegates object creation to the factory and uses the returned notification instance to send the message.public class NotificationService {
public void send(NotificationType type, String recipient, String message) {
Notification notification = NotificationFactory.create(type);
notification.send(recipient, message);
}
}
Example
This example sends notifications through different channels without the client needing to know which concrete notification class is instantiated.public class Main {
public static void main(String[] args) {
NotificationService service = new NotificationService();
service.send(NotificationType.EMAIL, "john@example.com", "Order Confirmed");
service.send(NotificationType.SMS, "9876543210", "OTP: 123456");
service.send(NotificationType.PUSH, "user-101", "New Offer Available");
}
}
Output:
Email sent to john@example.com: Order Confirmed
SMS sent to 9876543210: OTP: 123456
Push notification sent to user-101: New Offer Available
Complexity
Creating a notification implementation requires a constant-time factory lookup. Sending a notification depends on the external provider, while the application-side processing remains constant.Time Complexity
Create Notification β O(1)
Send Notification β O(1)
Space Complexity
O(1)