← Back to Advanced Java Course | Chapter 6: Design Patterns | Lesson 4 of 14

Java का Observer Pattern

Observer pattern कई objects को यह बताने देता है कि जब कोई एक चीज़ बदलती है, जैसे किसी के post करने पर followers को notice मिलना। वे sign up करते हैं, और अपने आप updates पाते हैं।
Syntax
java
interface Observer {
    void update(Data data);
}

class Subject {
    private List<Observer> observers = new ArrayList<>();
    void attach(Observer o) { observers.add(o); }
    void notifyAll(Data data) { for (Observer o : observers) o.update(data); }
}

Subject and Observer Interfaces

Observer Pattern objects के बीच एक one-to-many dependency define करता है: जब एक object, Subject, अपनी state बदलता है, तो उसके registered dependents, Observers, में से हर एक को अपने आप notify किया जाता है बिना Subject को उनके बारे में कुछ specific जानने की ज़रूरत के।

उदाहरण: Subject and Observer Interfaces

java
// Define the class Main
public class Main {
	// Define the interface Observer
	interface Observer { void update(String data); }
	// Define the interface Subject
	interface Subject {
		void attach(Observer o);
		void notifyObservers(String data);
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Print a line to the console
		System.out.println("Subject notifies every registered Observer automatically");
	}
}

Concrete Subject Implementation

एक Concrete Subject अपने observers को एक internal list में track करता है, observers को dynamically attach या detach करने के methods उजागर करते हुए। जब इसकी state बदलती है, यह उस list से गुज़रता है और उन्हें notify करने के लिए हर observer के update method को call करता है।

उदाहरण: Concrete Subject Implementation

java
// Import java.util.* so it can be used by its short name
import java.util.*;
// Define the class Main
public class Main {
	// Define the interface Observer
	interface Observer { void update(String data); }
	// Define the class NewsPublisher
	static class NewsPublisher {
		// Create a new ArrayList object and store it in observers
		List<Observer> observers = new ArrayList<>();
		void attach(Observer o) { observers.add(o); }
		void publish(String data) {
			for (Observer o : observers) o.update(data);
		}
	}
	// Program entry point: the JVM starts running here
	public static void main(String[] args) {
		// Create a new NewsPublisher object and store it in publisher
		NewsPublisher publisher = new NewsPublisher();
		publisher.attach(data -> System.out.println("Received: " + data));
		publisher.publish("Breaking news");
	}
}

Concrete Observer Implementation

एक Concrete Observer update method implement करता है जिसे Subject call करता है। उस method के अंदर, यह जो भी custom logic अभी-अभी मिले नए data को देखते हुए उपयुक्त हो उसे चलाता है, पूरी तरह स्वतंत्र रूप से कि बाकी observers उसी notification पर कैसे react करते हैं।

उदाहरण: Concrete Observer Implementation

java
public class Main {
	interface Observer { void update(String data); }
	static class LoggingObserver implements Observer {
		public void update(String data) {
			System.out.println("Logged: " + data); // independent of other observers
		}
	}
	public static void main(String[] args) {
		Observer observer = new LoggingObserver();
		observer.update("event occurred");
	}
}

Dynamic Subscriptions

Observers runtime पर dynamically किसी Subject से subscribe या unsubscribe कर सकते हैं, सिर्फ setup पर नहीं। यह flexibility उन observers से memory leaks रोकती है जिन्हें हटाया जाना चाहिए था, और सुनिश्चित करती है कि हर observer सिर्फ उन specific events को प्राप्त करे जिनमें असल में उसकी दिलचस्पी है।

उदाहरण: Dynamic Subscriptions

java
import java.util.*;
public class Main {
	interface Observer { void update(String data); }
	static class Subject {
		List<Observer> observers = new ArrayList<>();
		void attach(Observer o) { observers.add(o); }
		void detach(Observer o) { observers.remove(o); }
		void notifyEach(String data) { for (Observer o : observers) o.update(data); }
	}
	public static void main(String[] args) {
		Subject subject = new Subject();
		Observer o = data -> System.out.println("Got: " + data);
		subject.attach(o);
		subject.detach(o); // unsubscribed before the next notification
		subject.notifyEach("no listeners left");
	}
}

Java Built-in Alternatives

आधुनिक Java code आमतौर पर इस pattern को JDK की original built-in Observer/Observable classes की जगह custom, purpose-built listener interfaces से implement करता है, जो proper event ordering guarantees की कमी जैसी design limitations की वजह से Java 9 से deprecated हैं।

उदाहरण: Java Built-in Alternatives

java
public class Main {
	interface ChangeListener { void onChange(String value); } // custom listener, not java.util.Observable (deprecated since Java 9)
	public static void main(String[] args) {
		ChangeListener listener = value -> System.out.println("Changed to: " + value);
		listener.onChange("new state");
	}
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
आम गलतियां
  1. observers को कभी detach न करना, जिससे subject उनके references रखता है और वे garbage collect नहीं हो पाते।
  2. notifyObservers में list पर loop चलाते हुए observers जोड़ना या हटाना, जो ConcurrentModificationException फेंकता है।
  3. subject की state update होने से पहले observers को notify करना, जिससे उन्हें पुराना data मिलता है।

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.