Actually, it's the other way around. You attach or add an Observer
to an object that will be observed, an Observable
. You do that so that the observed object is able to notify
the observers once its state has changed.
In this pattern, if you were to subscribe a Subject
in an observer object and only do that. How could the observer know when the subject's state was changed the moment the action took place? Maybe the observer could start polling and asking about the subject's state until it changes and then the observer would act on it. But that is far from ideal.
That is kind of what happens with a WatchService
in which you, for instance, add a file to a service in order to be notified once the file is modified. Roughly, you're "subscribing" the subject in the observer. But here, you start a service that will take care of what you need behind the curtains.
Anyway, in your case, the best way would be to let the subject object manage the observers and call it whenever is appropriate.
Check out this link:
https://sourcemaking.com/design_patterns/observer
You must implement your class Subject
so that it receives entities that will observe its behavior and be notified as desired. It's the Subject's
duty to notify
the observers when a desired change has been made.
Java has its own implementation of the pattern. You should start by reading the Observable class to get the gist of it. Then, you should implement your own following the guidelines you've read. The idea is like this:
import java.util.ArrayList;
import java.util.List;
public class TestObserver {
public static void main(String[] args) {
Subject subject = new Subject();
ContentObserver contentObs = new ContentObserver();
subject.addObserver(contentObs);
// Once you call setContent, the object contentObs
// will be notified and print the desired text
subject.setContent("test");
}
}
class Subject {
private String content;
private List<ContentObserver> observers = new ArrayList<>();
public void addObserver(ContentObserver obs) {
observers.add(obs);
}
public void setContent(String content) {
this.content = content;
notifyContentObservers();
}
private void notifyContentObservers() {
observers.forEach(obs -> obs.update(content));
}
}
class ContentObserver {
public void update(String content) {
System.out.println("Content was changed! New content = " + content);
}
}
Remember that this is an example. You must manage your observers by adding, removing, etc. It's also advisable to code to an interface, so you should create your own Observer
interface according to what you want to observe.
Also, you shouldn't use the implementation provided by java as it's deprecated in java 9:
https://docs.oracle.com/javase/9/docs/api/java/util/Observable.html
https://dzone.com/articles/javas-observer-and-observable-are-deprecated-in-jd
If you want something more reliable and reactive. Take a look at:
https://docs.oracle.com/javase/9/docs/api/java/util/concurrent/Flow.html
Cheers!