MOBI BOOT CAMP CORP. logoLearning Buddy
  • SIGN IN
  • Introduction
  • 1. Build Tools & Project Structure
  • 2. The Web Layer (Servlets & JSP)
  • 3. Design Patterns & Architecture
    • Architectural Patterns (MVC, DAO, DTO)
    • Singleton Pattern
    • Factory Method Pattern
    • Builder Pattern
    • Strategy Pattern
    • Observer Pattern
  • 4. Persistence Foundations (SQL & JDBC)
  • 5. Object-Relational Mapping (ORM)
  • 6. Modern Web Services & Microservices
  • 7. Hands-on Project

Observer Pattern

The Observer Pattern is a behavioral design pattern that defines a one-to-many dependency between objects. When one object (the "subject" or "observable") changes its state, all its dependents ("observers") are notified and updated automatically.

This pattern is the cornerstone of event-driven programming. It promotes loose coupling between the subject and its observers; the subject doesn't need to know anything about its observers other than that they implement the Observer interface.

When to Use It

  • When a change to one object requires changing others, and you don't know how many objects need to be changed.
  • When you want to establish a publisher-subscriber model in your application.
  • When you want objects to be able to notify each other without being tightly coupled. Frameworks like Spring use this for application-wide events.

Structure

  1. Subject (Observable): An interface or abstract class that defines methods for attaching, detaching, and notifying observers.
  2. ConcreteSubject: Implements the Subject interface. It maintains the state and notifies observers when the state changes.
  3. Observer: An interface or abstract class that defines the update method, which is called by the subject when its state changes.
  4. ConcreteObserver: Implements the Observer interface and defines its reaction to the notification.

Example: A News Agency

Let's model a news agency that sends out news flashes. Multiple news channels can subscribe to this agency, and whenever a new story breaks, all subscribed channels receive the update instantly.

1. Observer Interface (Channel)

This is the interface that all observers (news channels) must implement.

package com.example.patterns.observer;

public interface Channel {
    void update(String news);
}

2. Subject (NewsAgency)

This is the subject that the observers will subscribe to. It maintains a list of observers and has methods to add, remove, and notify them.

package com.example.patterns.observer;

import java.util.ArrayList;
import java.util.List;

public class NewsAgency {
    private String news;
    private final List<Channel> channels = new ArrayList<>();

    // Add an observer
    public void subscribe(Channel channel) {
        this.channels.add(channel);
    }

    // Remove an observer
    public void unsubscribe(Channel channel) {
        this.channels.remove(channel);
    }

    // Notify all observers
    public void notifyChannels() {
        for (Channel channel : this.channels) {
            channel.update(this.news);
        }
    }

    // Method to update the state and notify observers
    public void setNews(String news) {
        this.news = news;
        System.out.println("News Agency: Breaking news! '" + news + "'");
        notifyChannels();
    }
}

3. Concrete Observers (NewsChannel)

These are the concrete implementations of the Channel interface. Each channel will have its own way of reacting to the news.

package com.example.patterns.observer;

public class NewsChannel implements Channel {
    private final String channelName;

    public NewsChannel(String channelName) {
        this.channelName = channelName;
    }

    @Override
    public void update(String news) {
        System.out.println("[" + this.channelName + "] Breaking News: " + news);
    }
}

4. Putting It All Together

The client code creates the subject (NewsAgency) and several observers (NewsChannel). It subscribes the observers to the subject and then triggers a state change.

package com.example.patterns.observer;

public class ObserverDemo {
    public static void main(String[] args) {
        // Create the Subject
        NewsAgency newsAgency = new NewsAgency();

        // Create Observers
        Channel bbc = new NewsChannel("BBC News");
        Channel cnn = new NewsChannel("CNN News");
        Channel fox = new NewsChannel("Fox News");

        // Subscribe observers to the subject
        newsAgency.subscribe(bbc);
        newsAgency.subscribe(cnn);
        newsAgency.subscribe(fox);

        // The subject's state changes, which should notify all observers
        newsAgency.setNews("Major tech company announces breakthrough in AI.");

        System.out.println("\n--- CNN unsubscribes ---\n");
        newsAgency.unsubscribe(cnn);

        // Another state change, only the remaining observers should be notified
        newsAgency.setNews("Stock market reacts positively to the news.");
    }
}

Output:

News Agency: Breaking news! 'Major tech company announces breakthrough in AI.'
[BBC News] Breaking News: Major tech company announces breakthrough in AI.
[CNN News] Breaking News: Major tech company announces breakthrough in AI.
[Fox News] Breaking News: Major tech company announces breakthrough in AI.

--- CNN unsubscribes ---

News Agency: Breaking news! 'Stock market reacts positively to the news.'
[BBC News] Breaking News: Stock market reacts positively to the news.
[Fox News] Breaking News: Stock market reacts positively to the news.

This demonstrates how the NewsAgency can notify multiple channels without being coupled to them. We can add or remove subscribers at any time without affecting the agency.

Privacy Policy | Terms & Conditions