Photo by tito pixel on Unsplash

Observer Pattern in Go

This is the second chapter of Head First Design Patterns book. Though the book has code snippets in Java, my attempt here is to implement the problem discussed in Go. Without further ado, let’s understand the use-case.

The problem statement

We are told to design a weather monitoring application. It consists of 3 sections

  1. Weather station : to record humidity, temperature and pressure
  2. Weather data : tracks data from the weather station and forwards it to the displays
  3. various display elements :
  • current conditions,
  • weather statistics,
  • a simple forecast, and
  • a heat index calculator
Let’s say this is the Weather Station
These are the displays, which may or may not represent the actual implementation.

Thought process

  • Weather station should collect the data, and notify the changes to the various devices.
  • In design terminology, the weather station is the subject, and the display devices are the observers.
  • Weather station is the single owner of the data, devices are dependent on it for any updates.
  • The common analogy often used here is that of publisher-consumer models.

Suppose you want to avail a newspaper subscription. Once you register for it, you get a daily copy. But the moment, your subscription ends, you no longer receive it.

  • For our use-case, a loosely coupled system provided by the Observer Pattern, will greatly benefit us.
  • The station is responsible in sending the collected data, it should not be bothered about how the observing devices use it.
  • Suppose a better index (e.g. WBGT) comes up and heat index becomes irrelevant, we should be able to freely add the new device, and remove the heat index device.
  • We would not want to modify the code for the subject, when the new observer (WBGT device) comes in.
  • Changes to either the subject or the observer should have no impact on each other.
  • Similarly, both should be reusable and independent to each other.

UML Class Diagram

Class Diagram showing the use of observer pattern (Source: Head First Design Patterns)

In the code, I have renamed a few things.

  • CurrentConditions is now CurrCondDisplay
  • StatisticsDisplay is now StatDisplay

The Code

Note as the measurements change, observers immediately reflect the changes

The output of the above code is

Current conditions: 80.0F degrees and 65.0% humidity.
Avg/Max/Min temperature = 80.0/80.0/80.0
Forecast : Improving weather on the way!
Heat index is 82.955345
Current conditions: 82.0F degrees and 70.0% humidity.
Avg/Max/Min temperature = 81.0/82.0/80.0
Forecast : Watch out for cooler, rainy weather!
Heat index is 86.901260
Current conditions: 78.0F degrees and 90.0% humidity.
Avg/Max/Min temperature = 80.0/82.0/78.0
Forecast : More of the same.

The complete code implementation can be found in my Github repository.

Language specifics

Note: Go channels which are idiomatic way of handling data in concurrent code (routines) can be applicable to this use-case. Perhaps, I’ll cover that in another article.

I found two ways of handling multiple inheritance.

  1. Composition of smaller interfaces to make a single interface.
type displayerObserver interface {
Displayer
Observer
}

2. Type assertion of structs.

...
func (sd *StatDisplay) update(temp float32, humidity float32, pressure float32) {
...
var d Displayer = sd
d.display()
...
}
// check statDisplay.go file for more detail

Takeaways

The book defines,

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.

Some interesting design principles arise

  1. Identify the aspects of your application that vary and separate them out from what stays the same.
  2. Program to an interface, not an implementation.
  3. Favour composition over inheritance.
  4. Strive for loosely coupled designs between objects that interact.

Do you see a mistake in there? Mention in the comments.

Did you like it? Show your support through claps 👏.

I’m Srinjoy Santra, currently an SDE-1 at BookMyShow. You can connect with me on LinkedIn, visit my Github account, or follow me on Twitter.

Coder, Amateur Musician, Blogger, Quora writer