Implementing Newsletter Subscription using Observer Design Pattern in Python
Last Updated :
12 Jan, 2022
Observer Design Pattern is a design pattern in Python that facilitates a one-to-many relationship. Say, for example, you and several other readers subscribed to a newsletter. When there is a new newsletter available, you will receive it along with other subscribers. Suppose, if you don't want to receive the newsletter, you can cancel your subscription and you will not receive the new editions.
An observer design pattern is not limited to the newsletter subscription. It can be any information such as a concurrent thread signal, a signal from an operating system, and so on. An observer design pattern is a form of a publishing-subscriber pattern. It facilitates managing subscriptions and broadcasting information to subscribers.
Benefits of Observer Design Pattern
Observer Design Pattern has a static object called Subject and a variable object called Observers. There can be zero or N number of observers, which can change based on subscription. Here, the Subject keeps the Observers, and if any of the object state changes, the Subject notifies other Observers. For example, consider the case of a LinkedIn post. When you post a new LinkedIn post (state change), the timeline of your followers is updated with your new post.
Let's look into its benefits.
- Facilitates a loose coupling between Subject and Observers
- Observers can be updated at runtime
- A subject can keep zero or N number of observers
- The aptitude of broadcasting messages between Subject and Observers.
Newsletter Subscription Implementation
Let's design a simple newsletter subscription model to understand the observer design pattern. As we discussed, an observer design pattern has two main objects – Subject and Observer. The subject can add, remove, and notify the observers through register_observer, unregister_observer, and notify_observer. Whereas, the observer is an interface that has an abstract method – notify.
Observer Design Pattern
Here, two concrete observers – CompanyNewsletterObserver and ConsumerNewsletterObserver – are derived from the Observer interface. These concrete methods implement the abstract method notify, and the Subject will call the notify method in its notify_observer method. So to send information to the subscribers, we simply need to call the notify_observer method in the Subject. Let's look into the implementation.
Python3
import abc
import time
import datetime
class Subject(object):
def __init__(self):
self.observers = []
self.cur_time = None
def register_observer(self, observer):
if observer in self.observers:
print(observer, 'already registered')
else:
self.observers.append(observer)
def unregister_observer(self, observer):
try:
self.observers.remove(observer)
except ValueError:
print('Cannot Identify the Observer')
def notify_observer(self):
self.cur_time = datetime.datetime.now()
for observer in self.observers:
observer.notify(self.cur_time)
class Observer(object, metaclass=abc.ABCMeta):
""" Abstract class for Observers """
@abc.abstractmethod
def notify(self, unix_timestamp):
pass
class CompanyNewsletterObserver(Observer):
""" Company Newsletter """
def __init__(self, name):
self.name = name
def notify(self, time):
print(self.name, ':', time)
class ConsumerNewsletterObserver(Observer):
""" Consumer Newsletter """
def __init__(self, name):
self.name = name
def notify(self, time):
print(self.name, ':', time)
if __name__ == '__main__':
subject = Subject()
print('Registering company_newsletter_observer')
cmp_observer = CompanyNewsletterObserver('company_newsletter_observer')
subject.register_observer(cmp_observer)
subject.notify_observer()
print()
time.sleep(2)
print('Registering consumer_newsletter_observer')
con_observer = ConsumerNewsletterObserver('consumer_newsletter_observer')
subject.register_observer(con_observer)
subject.notify_observer()
print()
time.sleep(2)
print('Unregistering company_newsletter_observer')
subject.unregister_observer(cmp_observer)
subject.notify_observer()
Output:
Registering company_newsletter_observer
company_newsletter_observer : 2020-10-15 20:40:04.335355
Registering consumer_newsletter_observer
company_newsletter_observer : 2020-10-15 20:40:06.336913
consumer_newsletter_observer : 2020-10-15 20:40:06.336913
Unregistering company_newsletter_observer
consumer_newsletter_observer : 2020-10-15 20:40:08.339662
You can refer to the above output to understand the behavior of code while registering and un-registering observers.
An observer design pattern best suits the need to achieve a one-to-many relationship. You can broadcast the same information to many listeners. And, the listeners can be added or removed at runtime. Here, the subject only has information about the observer's interface, which helps to maintain loose coupling between the subject and the observers.
Similar Reads
Implementing News Parser using Template Method Design Pattern in Python
While defining algorithms, programmers often neglect the importance of grouping the same methods of different algorithms. Normally, they define algorithms from start to end and repeat the same methods in every algorithm. This practice leads to code duplication and difficulties in code maintenance â
4 min read
Observer method - Python Design Patterns
The observer method is a Behavioral design Pattern which allows you to define or create a subscription mechanism to send the notification to the multiple objects about any new event that happens to the object that they are observing. The subject is basically observed by multiple objects. The subject
4 min read
Implementing Weather Forecast using Facade Design Pattern in Python
Facade Design Patterns are design patterns in Python that provide a simple interface to a complex subsystem. When we look into the world around us, we can always find facade design patterns. An automobile is the best example: you don't need to understand how the engine functions. To operate the engi
3 min read
Implementing Web Crawler using Abstract Factory Design Pattern in Python
In the Abstract Factory design pattern, every product has an abstract product interface. This approach facilitates the creation of families of related objects that is independent of their factory classes. As a result, you can change the factory at runtime to get a different object  â simplifies the
5 min read
Memento Method Design Pattern in Python
The Memento Design Pattern is a behavioral design pattern that allows you to capture and restore an object's state without revealing its internal structure. This pattern is particularly useful in implementing undo mechanisms. In this article, we will explore the Memento Method Design Pattern in Pyth
8 min read
Implementation of Queue using List in Python
A queue is a linear data structure that follows the FIFO (First In First Out) principle. The first element added is the first one to be removed. With a queue, the least recently added item is removed first. A good example of a queue is any queue of consumers for a resource where the consumer that ca
6 min read
Singleton Method - Python Design Patterns
Prerequisite: Singleton Design pattern | IntroductionWhat is Singleton Method in PythonSingleton Method is a type of Creational Design pattern and is one of the simplest design patterns available to us. It is a way to provide one and only one object of a particular type. It involves only one class t
5 min read
Visitor Method - Python Design Patterns
Visitor Method is a Behavioral Design Pattern which allows us to separate the algorithm from an object structure on which it operates. It helps us to add new features to an existing class hierarchy dynamically without changing it. All the behavioral patterns proved as the best methods to handle the
4 min read
Accessing Web Resources using Factory Method Design Pattern in Python
A factory is a class for building other objects, where it creates and returns an object based on the passed parameters. Here, the client provides materials to the Factory class, and the Factory class creates and returns the products based on the given material. A Factory is not a design pattern, but
4 min read
Strategy Method - Python Design Patterns
The strategy method is Behavioral Design pattern that allows you to define the complete family of algorithms, encapsulates each one and putting each of them into separate classes and also allows to interchange there objects. It is implemented in Python by dynamically replacing the content of a metho
3 min read