The Observer Pattern
A very simple explanation of the Observer Pattern
Overview
Today we’re going to be learning about the Observer design pattern in Java. As far as I’m aware, design patterns exist to solve common problems in software engineering. I chose Java because I like it. I’ll list my sources at the end. If you want to just read those instead I won’t be mad at you.
If you have any corrections please let me know at
[email protected]
So what problem does the Observer pattern solve?
This pattern is used when changes to one object may require you to make changes to other objects. The special fancy object who’s state is relevant to a group of other objects is called the subject
or the publisher
. I’m gonna use publisher
. The objects who care about the state of the publisher are called subscribers
.
The Publisher
The publisher
is responsible for:
- Keep track of subscribers (perhaps in a list)
- Provide a method to add subscribers
- Provide a method to remove subscribers
I also added a method to get and set the state of the publisher
object. This is what the observers care about. Changing this state will trigger the process of notifying all of our observers.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Publisher {
// our list of observers
private List<Observer> observers = new ArrayList<>();
// the state the all of the observers care so deeply about
private String state;
// put observer into list
public void addObserver(Observer observer) {
observers.add(observer);
}
// remove observer from list
public void removeObserver(Observer observer) {
observers.remove(observer);
}
// notify observers
private void notifyObservers() {
for (Observer observer : observers) {
observer.update(this);
}
}
// check the state of the special fancy object that has special info
public String getState() {
return state;
}
// set state of the special fancy object, then let everyone know
public void setState(String state) {
this.state = state;
notifyObservers();
}
}
When an event happens (the publisher
’s state changes value), the publisher
notifies all of its subscribers
in its list by looping through each of them, and calling their update()
method, passing in itself as an argument.
The Observer
The Observer
is fairly simple for this example. We’re just gonna have a method update()
to get the status of the publisher
. To enforce this, we’ll make an interface.
1
2
3
interface Observer {
void update(Subject subject);
}
Example of an Observer
class that implements this interface.
1
2
3
4
5
6
7
8
9
class ConcreteObserverA implements Observer {
@Override
public void update(Subject subject) {
System.out.println("Thank you publisher for giving yourself to me so i can check your state. This is it btw: " + subject.getState());
}
// add more Observers in the same way...
}
How the notification process works
- The
publisher
’sstate
changes- This calls the
notifyObservers()
method
- This calls the
- Inside
notifyObservers()
:- for each
Observer
in our list:- call their
update()
method, passing in thepublisher
object, so theobserver
can access itsstate
variable
- call their
- for each
- Execute whatever code is in the
observer
’supdate()
method - Move onto the next
observer
in the list
Putting it all together
Alrighty, time to put this all into practice in our main
method.
We’re gonna
- Instantiate our
publisher
andobserver
classes. (Observer reference type for super smart flexibility) - Add the
observer
object to thepublisher
’s list - Set the
state
ofpublisher
, which triggers all of the above section logic
Ok code time:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class ObserverPattern {
public static void main(String[] args) {
// make our publisher
Publisher publisher = new Publisher();
// make our observer
Observer observer = new ConcreteObserver();
// subscribe observer obj to publisher, aka add observer to its list
publisher.addObserver(observer);
// set the state of our publisher
publisher.setState("My new state, very important stuff");
}
}
Our amazing output:
1
Thank you publisher for giving yourself to me so i can check your state. This is it btw: My new state, very important stuff
Closing thoughts
So thats the pattern. I didn’t use the removeObserver()
method, but you can use that if you need to. I took me a second to grasp the concept of “notifying” other objects when another object’s state changes. But at its core, the Observer Pattern involves a publisher with a list of observers and iterating through those observers, calling their update(this)
method, and passing the publisher
object itself as an argument.
This is a pretty basic example of the pattern, just so you (and me) can become familiar with the basics. It can get a lot more complicated with more abstractions as you SOLID the hell out of it. That’s beyond me though, at least for right now. Check out the sources for more info about it, as well as the more complex implementations.
Thanks for reading, and again, let me know if you’ve got any corrections/improvement suggestions.
Sources:
- https://refactoring.guru/design-patterns/observer/java/example
- This is a great resource for learning about design patterns
- https://www.patterns.dev/vanilla/observer-pattern/