Design Pattern : Observer Pattern

Haririthanya
6 min readSep 13, 2021

--

Photo by tito pixel on Unsplash

`A behavioural design pattern that allows some objects to notify other objects about the change in their behaviour`

The observer pattern falls under the category of Behavioural Design patterns. These patterns are concerned about communication between objects.

Scenario

Let us understand the observer pattern in detail. We’ll take the help of three detectives - Sherlock Holmes (The consulting detective), Hercule Poirot (Belgium detective) and Miss Marple (An amateur detective, who solves crimes with her shrewd intelligence)

[✨Our favourite detectives are here to help us understand Observer Pattern✨].

So all our detectives are using their little grey cells for solving cases for clients and enjoying the process. Now for our purpose, let us consider they are working with a Detective Agency whose only job is to notify them when they get any information about a new crime from the police department and each of them can investigate in their own style. Later if they decide to solve cases only when someone approaches them , that too should be allowed. The overall picture is , the Detective Agency will collect news regarding a crime through different sources(Police sources) and will notify the detectives about it.

The detective agency collects information from three different sources and informs the detectives who are a part of the Detective Agency
Application overview

Converting this to a class diagram, so our goal is to notify our detectives when ever the sources give us new information.

Initial DetectiveAgency class

Our goal is to modify the informationReceived() method such that it updates the three detectives. We know that the DetectiveAgency class has getter methods for three values : location at which the incident took place, any leads/evidences in the spot, any witness information.

The informationReceived() method is called anytime new data regarding a new crime is available.

We’ll need to implement three detective classes that use these three information for investigation. Also let’s think about the future - the agency could hire more detectives or few detectives will like to work separately. So we need to think about expandability.

Let’s implement the code with the help of our discussions above.

DetectiveAgency class with informationReceived() method implemented
Implementation of DetectiveAgency class

There is something annoying with our code. For every new detective, we would have to alter the DetectiveAgency class. We seem to be using a common interface to communicate with the detective objects. Hmm….. we need to think how we can achieve it.

We are learning about Observer Pattern, so why not know what it does and comeback to our problem and apply it?

Understanding the Observer Pattern

We all know how a newspaper subscription works, a newspaper publisher begins publishing newspaper. When we want new newspapers, we subscribe to them and receive newspapers when there’s a new one. If we don’t want to receive newspaper, we unsubscribe them. The publisher continues to stay in business and people constantly subscribe and unsubscribe to the newspaper. So this is our Observer Pattern, only that publisher is called Subject and subscriber is called Observer.

`The Observer Pattern defines a one-to-many dependency between objects so that when one object changes state, all of its dependents are notified and updated automatically.`

We have one subject who notifies many observers. The observers are dependent on the subject, the observers are notified when there is a change in the state of the subject.

The overall class diagram of Observer Pattern
Class diagram of Observer Pattern

Advantages

With this approach let’s see what we are trying to achieve here.
1. The only thing the subject knows about an observer is that it implements a certain interface.
2. We can add new observers at any time. Because the subject has a list of objects that implement the Observer Interface hence we can add new observers at runtime. Likewise we can remove observers.
3. We can easily reuse a subject or observer if there is another use for it.
Changes to either of them will not affect each other.
You see the flexibility here ?

`Strive for loosely coupled designs between objects that interact`

Loosely coupled system minimise the interdependency between objects. Observer Pattern is a great example of loose coupling.

Now , we’ll design the class diagram for our problem statement.

The big picture

Our concrete observers implement a Detective interface that has the investigate() method.

Implementation

Now we got the diagram that shows the overall structure of our classes. So let’s start the implementation.
The register and remove observer methods take an observer object. The notifyObserver is called to notify all the objects when the Subject’s state has changed.

Implementation of Subject interface
Subject interface implementation

For our Observer interface we have the update method with three parameters. (For simplicity, the types of the three parameters are String here.)

Observer Interface implementation

In our DetectiveAgency implementation we use a List to maintain the observers and registerObserver() method to add new observers and removeObserver() to remove observer.By this way we can dynamically add or remove observers. The notifyObserver() is called when there is any update to the state (whenever any information is received, hence it is called inside informationReceived() method) . To test the application as we don’t have the real ‘sources’, hence we are using setInformation() method.

DetectiveAgency class implementation

Now, let’s implement the concrete observer class SherlockHolmes (the rest of the concrete observer class will be something similar to this, hence I am skipping its implementation)

SherlockHolmes implementation

Next we need to implement the ObserverPatternDemo class to test our code. Here I give dummy values for location, evidences and witness information. We are done ! Tadaa !

ObserverPatternDemo implementation

Not yet…. 😛

Improving our application

Say, Hercule Poirot doesn’t need information about evidences as he wants to categorise items as evidences from his perspective. There might be chances that in the future, concrete observers don’t need all the three parameters, sending the updated information through parameters will not be necessary. We need to figure out a way such that the observers will get the data it requires. Let’s see how we can achieve that.

Till now in our implementation, our subject pushes the updated state value to observers, what if the observers pull the value from subject ?. This new approach also helps us to add new parameter other than the three. We need not pass the additional new value in the update() method. This is how our concrete subject and concrete observer classes will change.

Changes in DetectiveAgency, SherlockHolmes classes and Observer Interface

We are using the Subject’s getter method to get the state’s value in the concrete observer classes. Also we have successfully applied the observer pattern to our demo application, our favourite detectives have helped us understand this behavioural pattern (Thanking them at this moment). Congratulations !

Hope you got to know about Observer Pattern in this blog. Thanks for reading! Any feedbacks or comments is much appreciated.

You can read my blog on Strategy pattern here. Stay tuned for more such contents.

--

--