Observer design pattern (also known as Publish/Subscribe) is a software design pattern, used when we are building a system where the state of one object affects the state of other objects. It is a key part of model-view-controller architectural pattern.

In a traditional MVC ( Model-View-Controller ) architecture, a model is a subject and a view is an observer. A view is notified when a model changes and responds accordingly. When the subject sends observers detailed information about what has changed, indiscriminately, this is known as the push model of the Observer pattern. When a subject sends only minimal information to its observers must ask for details explicitly, this is known as the pull model of the Observer pattern.

Observer Design Pattern

Ruby provides a simple mechanism to implement this design pattern using the Observable module. In this mechanism, the Notifier class uses the Observable module, which provides the methods for managing the associated observer objects.

The observable object must:

  • assert that it has #changed
  • call #notify_observers

An observer subscribes to updates using #add_observer, which also specifies the method called via notify observers. The default method for notify observers is update.

Public Instance Methods

Instance methods are methods that are called on an instance of a class. We can use the below methods while using Observer instances.

  • add_observer(observer, func=:update)

Adds observer as an observer on this object, so that it will receive notifications.

  • changed(state=true)

Set the changed state of this object. Notifications will be sent only if the changed state is true.

  • changed?()

Returns true if this object’s state has been changed since the last notify_observers call.

  • count_observers()

Return the number of observers associated with this object.

  • delete_observer(observer)

Remove observer as an observer on this object so that it will no longer receive notifications.

  • delete_observers()

Remove all observers associated with this object.

  • notify_observers(*arg)
Notify observers of a change in state if this object’s changed state is true.

How it works

First, we have to create a basic structure of the Notifier class which will act as an Observer. The update() method is the callback that the Observable module will use when notifying changes to the observer, and the method name needs to be update().

Let’s take an example of an application which keeps track of the bike mileage and reminds us of when we need to take the vehicle in for a scheduled bike service.

Next, write the update method in Notifier class

By running the code we can see

First, we create an instance of the Bike class with 2300 miles, and we set that it needs to be taken for service when it reaches 3000 miles.

I hope this example helps you understand ruby observer design pattern better.

Let me know in comments if you have any doubts or any implementation issues you have been facing recently. Thanks for reading!

References