Subscribe to newsletter
Surely you’ve seen a website that has newsletters you can subscribe to before.
The goal of newsletter is, instead of having the user visit the website every day, the website sends them a message to notify them that there’s an update. Depending on the website, the message contains either a short summary or the full article.
Subscribing to the newsletters of a website you’re interested in is a good idea because it saves your time: instead of visiting the website every day to check for updates, you only visit the website when you receive a newsletter.
The observer pattern is a pattern in which a list of dependant objects (observers
) are notified by the subject
when
the state held by the subject
changes.
The subject contains both the state (what the observers wants to be notified about) and the list of observers (who wants to be notified).
Each observer must register themselves to the subject in order to be notified, similarly to a user that subscribes to a newsletter: unless subscribed, he will not be notified.
public class Subject {
private List<Observer> observers = new ArrayList<>();
private int state;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
notifyAllObservers(); // every time the state is updated, the observers must be notified
}
public void registerObserver(Observer observer) {
observers.add(observer);
}
public void notifyAllObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
An observer can either be an interface or an abstract class, but for the sake of this example, it’ll be an abstract class.
public abstract class Observer {
protected Subject subject;
public abstract void update();
}
public class SomeObserver extends Observer {
public SomeObserver(Subject subject) {
this.subject = subject;
this.subject.registerObserver(this);
}
@Override
public void update() {
System.out.println("Subject state has been updated to " + subject.getState());
}
}
Instead of having multiple classes constantly checking for updates on the same class (subject
), the subject
notifies the classes that it changed, causing those classes to update only when necessary.
In other words, rather than having the following in every class:
while (true) {
if (subject.hasChanged()) {
doSomething();
}
}
You have the following only present in the subject:
// this is called every time the state held by the subject is updated
for (Observer observer : observers) {
observer.update();
}