Understanding Observer and Observable Classes in Java

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

What are the observer and observable classes in Java? Explain with examples?

回答:

In Java, the Observer and Observable classes are part of the Observer design pattern, which is used to establish a one-to-many dependency between objects. When one object (the subject) changes its state, all its dependents (observers) are notified and updated automatically. This pattern is particularly useful in scenarios where a change in one object requires updates in others, such as in event handling systems.

Observable Class

The Observable class is a part of the java.util package and provides methods to manage a list of observers. It allows an object to be observed by other objects. The Observable class has methods to add, delete, and notify observers.

Observer Interface

The Observer interface, also part of the java.util package, must be implemented by any class that wants to be notified of changes in an Observable object. It has a single method, update, which is called when the observable object changes.

Example

Here’s a simple example demonstrating the use of Observable and Observer:

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

// Step 1: Create a class that extends Observable
class WeatherData extends Observable {
    private float temperature;
    private float humidity;

    public void setMeasurements(float temperature, float humidity) {
        this.temperature = temperature;
        this.humidity = humidity;
        setChanged(); // Mark this Observable as having been changed
        notifyObservers(); // Notify all registered observers
    }

    public float getTemperature() {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }
}

// Step 2: Create a class that implements Observer
class CurrentConditionsDisplay implements Observer {
    private float temperature;
    private float humidity;

    @Override
    public void update(Observable o, Object arg) {
        if (o instanceof WeatherData) {
            WeatherData weatherData = (WeatherData) o;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
            display();
        }
    }

    public void display() {
        System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity");
    }
}

// Step 3: Demonstrate the Observer pattern
public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay();

        // Register the observer
        weatherData.addObserver(currentDisplay);

        // Simulate new weather measurements
        weatherData.setMeasurements(80, 65);
        weatherData.setMeasurements(82, 70);
        weatherData.setMeasurements(78, 90);
    }
}

Explanation

  1. WeatherData Class: This class extends Observable. It has a method setMeasurements that updates the temperature and humidity. After updating the values, it calls setChanged() to indicate that the state has changed and then calls notifyObservers() to notify all registered observers.

  2. CurrentConditionsDisplay Class: This class implements the Observer interface. The update method is overridden to receive updates from the WeatherData object. When notified, it retrieves the new temperature and humidity and calls the display method to show the current conditions.

  3. WeatherStation Class: This is the main class where the program runs. It creates an instance of WeatherData and CurrentConditionsDisplay, registers the display as an observer, and simulates new weather measurements.

Note

As of Java 9, the Observable class and Observer interface are considered somewhat outdated, and their use is discouraged in favor of more modern approaches, such as using the java.beans package or reactive programming libraries like RxJava. However, the example above illustrates the basic concept of the Observer pattern in Java.