Observer Pattern

Tanish
5 min readMar 6, 2022

--

I know you don’t want to miss out when a meeting about design patterns happen. But you don't know when it would happen, and you cant ask every day to host, right? We’ve got a pattern to rescue you. It will notify you when a meeting happens. Let's dive right in without wasting any time. Before diving in, I highly recommend you should checkout Strategy Pattern.

Hakim has started a new Franchise of burgers and fortunately! he got 3 restaurants that want his burgers to serve. Whenever Hakim changes his recipe or invents a new burger, he needs to notify restaurants(his subscribers) about his changed or new burger so that they don't miss out or leave behind. He is an OOPS expert so he thinks he can design his system to notify his subscribers.

Let's look at his design-

Fig 1: Hakim design

He is too happy with his design, he is able to notify his subscribers whenever he changes/removes/invents a burger. But whenever he gets a new subscriber he needs to change his code and now he has got some 100 subscribers. So he is not able to handle it. As you are a good friend of him, therefore he asked you to design his system. You already have some design principles in your pocket and just aced the deal of SimUDuck App. So you decided to help him out and show him Design patterns are so important for software development.

Let's first look at the flaws in hakim design, try to see which Design principle he is violating:

  1. He is hard-coding, so we have no way to add or remove subscribers to/from his list.
  2. There is an area that is varying, so we need to encapsulate it.
  3. One thing is good, he has used a common interface for his restaurants(subscribers).

Let's try to fix them, you just heard of a new Design Principle:

Strive for loosely coupled designs between objects that interact.

As restaurants are also taking other franchises' recipes. So we need a common interface for Franchise, let's call it Subject Interface. It will have 3 methods register(),remove() and notify() and hakim franchise will implement it. Hakim can sell his burger to other cafes, so we need a common interface to cover all subscribers, let's call it Observer. All Subscribers will implement it and they will also implement Restaurant Interface. Let's look at the UML diagram-

whenever something happens with burgers, all subscribers will get notified. Subscribers can unsubscribe when they want and any new restaurant can subscribe without any alteration of code. It's wonderful and working fine. you deliver this to hakim, he is very happy with you after all you made his job easy.

But some years later, hakim called you and said your design is not working anymore. Some of the subscribers are getting burgers even they don't want. Actually, hakim started to serve pizza also. So some subscribers only want pizza but they are getting pizza and burgers both, same for burger subscribers.

So what is the flaw here? you have followed all design principles then, what could it be!!!

Actually, we are pushing notifications to our subscribers, don't care what type of notifications they want. So instead of pushing, let them pull information. These are the following few small changes to our existing code.

With this design, subscribers can get info that they desire and as we already fulfilling our previous requirements. So It seems to work fine. Hakim is also doing great and has got many different types of subscribers.

And with that, you have successfully implemented the Observer pattern. Let's look at the formal definition of Observer Pattern and then some examples:

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.

The Subject and observers define the one-to-many relationship. We got one subject who notifies many observers. Observer Pattern is a great example of loose coupling. Loosely coupled allow us to build a flexible OO design that can handle change because they minimize the interdependency between objects that interact.

Takeaway: Use Observer Pattern when we have publisher+subscriber type model.

Pros:

  1. The only thing the subject knows about an observer is that it implements an Observer interface.
  2. can add new observers at any time without the need to alter the subject.
  3. can reuse subject or observers independently of each other.
  4. Changes to either the subject or an observer will not affect the other.

Here are some examples to get more clarity:

Example1: We need to build our Weather monitoring station.The weather station will be based on weather data object, which tracks current weather conditions(temp, humidity and pressure).We need to create an app that provides three display elements: current condition, weather statistics and a simple forecast all updated in real time as weather data object changes.

Hint: Try to find out the subject and observer

Solution: Our Subject is a weather object, and observers are display. Let's look at the design

Example2: Think how a medium subscription works. you subscribed to some authors and when they publish something you will get notified. It is a little complex but on a high level, here they(medium developers) are using observer pattern to achieve this. In this case, we readers are observers, medium is a subject that has lot of stories(currently don't care from where it is coming).

Thank you so much for sticking with me. I hope you got a better understanding of the observer pattern and its implementation and uses. I have attached code and UML diagrams for more clarity. Please find them. And if anyone would like to discuss more, please ping me on LinkedIn and if you are interested to learn more about design patterns, stay tuned for the next post.

P.S: This post is inspired by Head First Design Pattern. I highly recommend if you want to know the logic behind Design Pattern checkout this book.

github: https://github.com/excelo0702/WatABurger/tree/HakimDesign

--

--

Tanish

Software Developer at Salesforce- Design Pattern Enthusiast, MNNIT Allahabad