Introduction
This article outlines the observer design pattern. This behavioral design pattern defines a one-to-many dependency between objects such that if the object (subject) changes state, all other objects (observers) depending on this subject are notified of the change and updated automatically. This model therefore makes it possible to set up a mechanism for sending notifications between objects after their observers. We go over how to use it, examine a case study, and apply this pattern using the Java programming language in the next sections of this post.
The YouTube Channels in both English (En) and French (Fr) are now accessible, feel free to subscribe by clicking here.
Context
Let’s imagine a stock management application in a warehouse. This application includes several components:
- A user interface component that displays stock levels in real-time.
- An alert system that sends email notifications when stock reaches a critical level.
- A statistics module that records stock changes for later analysis.
When the stock level changes (for example, due to a sale or new delivery), all parts of the system must be updated:
- The real-time display should show the new stock level.
- The alert system should check whether a notification should be sent.
- The statistics module should register the change.
Without the Observer pattern, each component would have to directly query the inventory state and react accordingly, which would create strong coupling and make the system difficult to maintain and expand.
Using the Observer pattern, the inventory management system can be designed so that the components are observers that register with the subject (the inventory). Every time the stock level changes, the subject notifies all registered observers.
Design Pattern Observer Architecture

Let’s explain this architecture a little:
- Subject: The object that contains the state and whose changes are to be monitored. In other words, it is an object that maintains a list of observers, provides methods for adding and removing observers, and notifies all observers when its state changes. In our example, this could be the Stock class.
- Observer: Interface or abstract class that objects must implement to receive change notifications. That is, it defines an interface to be notified of changes in the state of the subject, for example, StockObserver.
- ConcreteObserver: A concrete implementation of the observer that reacts to notifications from the subject. That is to say, it maintains a reference to a concrete subject, updates its state so that it’s in phase with that of the subject, and implements the update() method to react to notifications from the subject, for example, StockDisplay and StockChart.
Design Pattern Observer Use Cases
The Observer design pattern is commonly used in many use cases where it is necessary to maintain a dependency relationship between objects such that when the state of an object changes, all dependent objects are notified, and updated automatically. Here are some real-world examples of use cases for the Observer pattern:
- Reactive User Interfaces: Often in applications with GUIs, views (user interfaces) must be updated in response to changes in the underlying data.
- Notification Systems: Systems where it is necessary to notify multiple stakeholders or systems in response to an event.
- Model-View-Controller (MVC): The Observer pattern is often used in MVC architectures to ensure synchronization between the model and the view.
- Etc.
Design Pattern Observer in Java
Case Study
We will take as an example a small application that manages grades to illustrate the implementation of the observer pattern in Java.
By following the architecture of the observer pattern, we will have:
1. Subject: Student
2. Observer: Observer
3. ConcreteObserver: GradessObserver

Technical Implementation
The Subject Class:
package com.faelma.pattern.observer;
import java.util.ArrayList;
import java.util.List;
public class Student {
private List<Observer> observers;
private List<Float> grades;
private float average;
public Student() {
observers = new ArrayList<Observer>();
grades = new ArrayList<Float>();
}
public void AddGrades(float grade) {
grades.add(grade);
notifyAllObservers();
}
public void setAverage(float average) {
this.average = average;
}
public float getAverage() {
return average;
}
public List<Float> getGrades() {
return grades;
}
public void attach(Observer observer){
observers.add(observer);
}
private void notifyAllObservers() {
for (Observer observer : observers) {
observer.notify();
}
}
}
The Observer Interface:
package com.faelma.pattern.observer;
public abstract class Observer {
protected Student student;
public abstract void notify();
}
The ConcreteObserver class (GradesObserver):
package com.faelma.pattern.observer;
public class GradesObserver extends Observer{
private Student student;
public GradesObserver(Student student) {
this.student = student;
this.student.attach(this);
}
@Override
public void notify() {
float average = 0;
for (float grade : student.getGrades()) {
average += grade;
}
average /= student.getGrades().size();
student.setAverage(average);
}
}
The Client:
package com.faelma.pattern.observer;
public class ObserverMain {
public static void main(String[] args) {
Student student = new Student();
new GradesObserver(student);
student.addGrades(15.0f);
System.out.println(student.getAverage());
student.addGrades(5.0f);
System.out.println(student.getAverage());
student.addGrades(13.0f);
System.out.println(student.getAverage());
}
}
Result:
com.faelma.pattern.observer.ObserverMain
15.0
10.0
11.0
The full source code is available on GitHub.
Advantages and Disadvantages
The use of the Observer pattern in the field of software development can present advantages and disadvantages in multiple situations. Below, we present some advantages and disadvantages of this model.
Design Pattern Observer Advantages
- It is not necessary to modify the subject code to add new observer classes, and vice versa for the subject. This allows us to respect one of the SOLID principles: the open/closed principle.
- It is possible to create links between objects when running the application.
- The idea of loose coupling, which describes how items interact with one another, is preserved.
Design Pattern Observer Disadvantages
- Objects that subscribe are informed randomly, that’s to say we cannot choose the order in which the objects (observers) are notified.
- In the subject’s source code, it is not possible to determine the recipient of the information.
- If not correctly implemented, the
Observer
can add complexity.
———————
We have just started our journey to build a network of professionals to grow even more our free knowledge-sharing community that’ll give you a chance to learn interesting things about topics like cloud computing, software development, and software architectures while keeping the door open to more opportunities.
Does this speak to you? If YES, feel free to Join our Discord Server to stay in touch with the community and be part of independently organized events.
———————
Conclusion
The Observer pattern solves the synchronization problem between dependent objects while reducing their coupling. It provides an elegant solution for dynamic dependency management and improves system maintainability and flexibility.
Thanks for reading this article. Like, recommend, and share if you enjoyed it. Follow us on Facebook, Twitter, and LinkedIn for more content.