observer and observable in java example

Sheila 62 Published: 11/05/2024

observer and observable in java example

I'm happy to help!

Observer Design Pattern: A Simple Java Example

The Observer design pattern is a behavioral pattern that allows an object (the subject or observable) to notify other objects (observers) when its state changes.

Here's a simple example in Java:

// The Subject, Observable class

public interface Subject {

void registerObserver(Observer observer);

void removeObserver(Observer observer);

void notifyObservers();

}

// The Observer class

public abstract class Observer {

protected String name;

public Observer(String name) {

this.name = name;

}

// Define an update method which will receive the notification

public abstract void update();

}

// A specific ConcreteObserver for Temperature

public class TemperatureObserver extends Observer {

public TemperatureObserver(String name) {

super(name);

}

@Override

public void update() {

System.out.println("TemperatureObserver: Temperature has changed!");

}

}

// Another specific ConcreteObserver for Humidity

public class HumidityObserver extends Observer {

public HumidityObserver(String name) {

super(name);

}

@Override

public void update() {

System.out.println("HumidityObserver: Humidity has changed!");

}

}

// The WeatherStation, which is the subject observable

public class WeatherStation implements Subject {

private List observers;

private int temperature;

public WeatherStation() {

this.observers = new ArrayList<>();

this.temperature = 0;

}

@Override

public void registerObserver(Observer observer) {

this.observers.add(observer);

}

@Override

public void removeObserver(Observer observer) {

this.observers.remove(observer);

}

@Override

public void notifyObservers() {

for (Observer observer : observers) {

observer.update();

}

}

// The actual weather station logic goes here...

public void setTemperature(int temperature) {

System.out.println("WeatherStation: Temperature has changed to " + temperature);

this.temperature = temperature;

notifyObservers(); // Notify all registered observers

}

}

public class Main {

public static void main(String[] args) {

WeatherStation weatherStation = new WeatherStation();

TemperatureObserver tempObserver = new TemperatureObserver("Temp Observer");

HumidityObserver humidityObserver = new HumidityObserver("Humidity Observer");

weatherStation.registerObserver(tempObserver);

weatherStation.registerObserver(humidityObserver);

// Simulate temperature change

weatherStation.setTemperature(30);

// Simulate another temperature change

weatherStation.setTemperature(20);

// Remove the temperature observer, no notifications should be sent for this change

weatherStation.removeObserver(tempObserver);

// Another temperature change after removing tempObserver

weatherStation.setTemperature(10);

}

}

This example demonstrates how multiple observers (TemperatureObserver and HumidityObserver) can register themselves with a subject (WeatherStation). When the WeatherStation's state changes, it notifies all registered observers by calling their update methods.

The key benefits of this design pattern are:

Decoupling: The observers are decoupled from each other and the weather station. They only depend on the Subject interface. Notification: The subject (WeatherStation) can notify multiple observers about state changes without having a direct reference to them.

In the provided example, when the temperature in WeatherStation changes, it notifies all registered TemperatureObserver and HumidityObserver instances.

java observer pattern vs listener

The Observer Pattern and the Listener (or Event Handling) pattern are two popular design patterns used to manage interactions between objects. While they share some similarities, they have distinct differences.

Observer Pattern:

In the Observer pattern, you have a subject (also known as the publisher or provider) that maintains a list of dependencies (observers). When the subject's state changes, it notifies all its observers, allowing them to react accordingly. This decouples the subject from the specific actions taken by the observers.

The Observer pattern is often used in situations where:

Publish-Subscribe: The subject publishes events or data, and multiple observers subscribe to receive notifications. Asynchronous processing: Observers can process events in parallel, without blocking the subject's execution. Decoupling: The subject doesn't depend on specific observer actions.

In Java, you can implement the Observer pattern using:

Observer interface: Define an Observer interface with a single method, update(), which will be called by the subject when it notifies its observers. Subject class: Implement a Subject class that maintains a list of observers and notifies them when their state changes.

Listener (or Event Handling) pattern:

In the Listener pattern, an event source publishes events to one or more event listeners. Each listener is responsible for handling the received event. The event source does not know about the specific listeners; it only knows that there are listeners registered to receive its events.

The Listener pattern is often used in situations where:

Event-driven programming: Events trigger actions, rather than having objects poll each other. Single-source, multiple-targets: One source publishes events to multiple targets (listeners). Loose Coupling: The event source doesn't depend on specific listener actions.

In Java, you can implement the Listener pattern using:

Event interface: Define an Event interface that provides a way for listeners to access the event data. Listener interface: Define a Listener interface with a method that will be called by the event source when it publishes an event. Event source class: Implement an EventSource class that publishes events to registered listeners.

Key differences:

Direction of communication: In the Observer pattern, the subject notifies its observers; in the Listener pattern, the event source publishes events to listeners. Observer vs Listener: Observers are responsible for processing state changes, while listeners handle specific events. Number of observers/listeners: The Observer pattern can have multiple subjects and observers, whereas the Listener pattern typically has one event source and multiple listeners.

When deciding between these two patterns:

Use the Observer pattern when you need to decouple the subject from observer actions or process state changes asynchronously. Choose the Listener pattern for event-driven programming with single-source, multiple-targets scenarios where loose coupling is beneficial.

In conclusion, while both patterns allow for object interactions and decoupling, they differ in their communication direction, responsibilities of participants, and use cases. By understanding these differences, you can select the most suitable pattern for your Java application's requirements.