In the world of software, there are generally multiple services interacting with one another to perform even a single operation. Lets say for example – sending an email.
This one single operation that is carried out: actually dependent upon the underlying objects of the services and how these objects interact with one another.
Let us try to understand how these objects and services come into play and form the basis of the Observer Design Pattern . . .
Let’s assume that you want to follow every blog posts that gets published here in debuggers hub. Now, In order to do that, you first need to get subscribed to the website. So whenever a new blog gets published or there are any new updates, you will be instantly notified.
The way that debuggers hub notifies you could be through email or some kind of notification service that is defined internally.
This is where things start to get interesting – Just like you, there can be hundreds or thousands of other subscribers who would want to get instantly notified of any new updates and blog posts.
Is that even possible ? How can we make the system behave in such a way ?
This is exactly where the Observer Design Pattern comes into play.
The intention here is to make the system behave in a certain way. That is the reason why this pattern falls under the category of the Behavioral pattern.
Check out this diagram to see where this pattern lies among all the categories of software design patterns.
Goals of the Observer Design Pattern:
To maintain a one to many dependency between objects.
(i.e any changes in one object should be notified to other dependent objects automatically)
Encapsulates the core component of the subject.
Actors in an Observer Design Pattern
There are three main participants in the observer design pattern:
- Subject ( An object having methods to attach, detach an observer to a client )
It manages a list of observers and notifies them of any state changes.
It also provides various methods like attach, detach to let the observers register and un-regsiter to a client.
Has a sole responsibility of getting themselves registered (or un-registered) on a Subject in order to get notified of any state changes and update themselves accordingly.
(i.e synchronize themselves with the state of the Subject)
The client configures the number and type of Observers.
A Practical Example
Taking an example of this website (debuggershub), Let us implement the observer design pattern in python.
Here, the Subject behaviour is represented by the BlogPublisher class. It is an interface for the subscribers to implement.
attach() method is user by the observer to register into the BlogPublisher.
detach() method for deregistering the observer.
subscriber() method returns a list of registered subscribers.
notifySubscriber() method iterates over the registered subscribers.
addBlog() method is used by the publisher to create a new Blog.
getBlog() method is used to return the latest blog which is notified to the Observer.
Here the Subscriber is an abstract base class which represents the Observer.
It has an update() method which is implemented by a ConcreteObserver class so that they get notified by the BlogPublisher.
Assuming that this website notifies its subscribers through either an SMS or an Email, we have created two classes – SMSSubscriber and EmailSubscriber. You can create any number of subscribers for example the AnyOtherSubscriber class.
The init() method initializes and registers (via the attach() method) a new ConcreteObserver class to the BlogPublisher ( the Subject).
The update() method is called by the BlogPublisher to notify the observer.
Here, The client initializes an instance of the BlogPublisher class and lists out the number of subscribers that have subscribed.
Once a blog is added, we notify the subscribers via the notifySubscribers() method.
Grab the full source code from the following link:
We will go through proxy design pattern in the next topic of design patterns in python.