Implementation and Application Scenarios of the Observer Pattern in Java

Dec 03, 2025 · Programming · 9 views · 7.8

Keywords: Observer Pattern | Java Design Patterns | Observable and Observer

Abstract: This article delves into the implementation of the Observer and Observable design pattern in Java, using a message board and student subscription example to analyze the core mechanisms, including state management in Observable, update methods in Observer, and the key roles of setChanged() and notifyObservers(). By drawing analogies to Twitter, it clarifies the pattern's value in decoupling object dependencies, providing clear technical guidance for developers.

Basic Concepts of the Observer Pattern

The Observer pattern is a behavioral design pattern that defines a one-to-many dependency, where when an object (called Observable) changes state, all its dependents (called Observers) are automatically notified and updated. In Java, this pattern is implemented through the java.util.Observable class and java.util.Observer interface, offering a standardized solution for developers.

Mechanism of Observable and Observer

The Observable class maintains a list of Observers, allowing them to register interest via the addObserver() method. When the Observable's state changes, it calls setChanged() to mark itself as changed, then iterates through the Observer list using notifyObservers(), triggering each Observer's update() method. This mechanism ensures loose coupling between Observable and Observer, as Observable does not need to know the specific implementation of Observers, only adhering to the interface contract.

Code Example Analysis: Message Board and Student Subscription

The following code example demonstrates the practical application of the Observer pattern:

import java.util.Observable;
import java.util.Observer;

class MessageBoard extends Observable {
    public void changeMessage(String message) {
        setChanged();
        notifyObservers(message);
    }
}

class Student implements Observer {
    @Override
    public void update(Observable o, Object arg) {
        System.out.println("Message board changed: " + arg);
    }
}

public class MessageBoardTest {
    public static void main(String[] args) {
        MessageBoard board = new MessageBoard();
        Student bob = new Student();
        Student joe = new Student();
        board.addObserver(bob);
        board.addObserver(joe);
        board.changeMessage("More Homework!");
    }
}

In this example, MessageBoard acts as the Observable, and when changeMessage() is called, it first marks the state change, then notifies all registered Student Observers. Each Student's update() method is invoked, outputting the message change. This simulates real-world subscription mechanisms, such as Twitter's follow feature, where users (Observers) follow accounts (Observables) to receive updates.

Role of setChanged() and notifyObservers()

The setChanged() method sets an internal flag in Observable to indicate that the object has changed. This is necessary because notifyObservers() checks this flag and only notifies Observers if the state has changed. This design allows for batch updates or delayed notifications, improving efficiency. For instance, if an Observable has multiple consecutive changes, developers can call notifyObservers() once after all changes are complete, avoiding unnecessary frequent notifications.

Application Scenarios and Advantages

The Observer pattern is suitable for scenarios requiring dynamic notifications to multiple objects, such as GUI event handling, message publish-subscribe systems, or data monitoring. Its core advantage lies in decoupling: Observable and Observer can evolve independently, reducing code dependencies. By using interfaces, Observers can implement custom behaviors, while Observable only manages notification logic. This enhances system scalability and maintainability.

Conclusion

Observer and Observable provide an efficient way to implement communication between objects, based on an event-driven architecture. Understanding the mechanisms of setChanged() and notifyObservers() is key, as they ensure precise and flexible notifications. In practical development, this pattern simplifies complex interactions and is a powerful tool for building responsive systems.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.