👀 Observer Design Pattern in Java
In dynamic applications where changes in one object need to be automatically reflected across others, the Observer Design Pattern is the go-to solution.
It enables a one-to-many dependency between objects so when one object (the Subject) changes state, all its dependents (the Observers) are notified automatically.
🌍 Real-World Analogies for the Observer Pattern
1. YouTube Channel & Subscribers
2. Newsletter Subscription
// Subscriber.java
// A subscriber can subscribe the youtube channel in multiple way like through email,sms, youtube push notification
package LLD.ObserverDesign;
interface Subscriber{
void getnotify();
String getName();
}
class BellIcon implements Subscriber{
private String name;
BellIcon(String name){
this.name=name;
}
public void getnotify() {
System.out.println(name+ " subscriber is notified through bell icon");
}
public String getName(){
return this.name;
}
}
class Email implements Subscriber{
private String name;
Email(String name){
this.name=name;
}
public void getnotify() {
System.out.println(name+" subscriber is notified through Email");
}
public String getName(){
return this.name;
}
}
class Sms implements Subscriber{
private String name;
Sms(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void getnotify() {
System.out.println(name+" subscriber is notified through Sms");
}
}
// YoutubeChannel.java
// Here we declare the youtubechannel interface and its concreate implementation.
package LLD.ObserverDesign;
import java.util.*;
interface YouTubeChannel {
// Method to add a new subscriber
void addSubscriber(Subscriber subscriber);
// Method to remove a subscriber
void removeSubscriber(Subscriber subscriber);
void notifySubscribers(); // Method to notify all subscribers
void addcontent();
}
class YoutubeChannelclass implements YouTubeChannel {
private String channelName;
private List<Subscriber> allsubs = new ArrayList<Subscriber>();
YoutubeChannelclass(String name) {
this.channelName = name;
System.out.println("Creating a youtube channel of name: " + channelName);
}
public void addSubscriber(Subscriber sub) {
System.out.println("Adding subscriber: " + sub.getName() + " to channel " + channelName);
allsubs.add(sub);
}
public void removeSubscriber(Subscriber sub) {
System.out.println("Removing subscriber:"+sub.getName()+" "+channelName);
allsubs.remove(sub);
}
// Notify All Subs
public void notifySubscribers() {
System.out.println("Notify all subscriber of: " + channelName);
for (Subscriber sub : allsubs) {
sub.getnotify();
}
}
public void addcontent() {
System.out.println("Adding a new video to youtube: "+channelName);
notifySubscribers(); // notify the subs abt new video
}
}
// Clien code Main.java
package LLD.ObserverDesign;
public class Main{
public static void main(String[] args){
System.out.println("Hello World from Main.java");
// lets create some youtube channel
YoutubeChannelclass travel=new YoutubeChannelclass("travel");
YoutubeChannelclass foodBlog=new YoutubeChannelclass("foodBlog");
// create few subscriber
Sms obs1=new Sms("obs1");
BellIcon obs2=new BellIcon("obs2");
Email obs3=new Email("obs3");
BellIcon obs4=new BellIcon("obs4");
// add the subs to channel
travel.addSubscriber(obs1);
travel.addSubscriber(obs4);
foodBlog.addSubscriber(obs3);
foodBlog.addSubscriber(obs2);
// add content on channel
travel.addcontent();
System.out.println("");
foodBlog.addcontent();
}
}
✅ When to Use Observer Pattern
🚫 When Not to Use It?
📌 Final Thoughts
The Observer pattern helps you build reactive and decoupled systems. It's particularly powerful in event-driven architectures, especially when implemented with thread safety in mind.
It promotes scalability, flexibility, and better separation of concerns.
🔁 Have you used the Observer pattern in a real-world project? 👇 Share your use cases or challenges in the comments.
#Java #DesignPatterns #ObserverPattern #EventDriven #Multithreading #SoftwareEngineering #CodingTips #JavaDeveloper #SystemDesign #CleanArchitecture