Observer Design Pattern
Publisher + Subscriber = Observer Design Pattern
There is an object which makes the publication of data and many objects are consuming that data. So these objects are called observer or subscriber.
Before we start, we are going to discuss about loose coupling and one-to-many relationship.
Loose coupling: Two objects can interact but have very little knowledge of each other, then they are loosely coupled. We can have some benefits for being loosely coupled. As we have publishers and subscribers, changes of publisher or subscriber will not affect each other. We can reuse those objects independently. We can add any subscriber at any time without modifying the publisher. They have the minimum dependency to each other. This allows us to develop flexible object oriented systems.
One-to-many relation: In the observer design pattern, publisher is an object who has the data or state and controls it. The subscribers, who consume that data or state but they don't have the ownership of that data. There are many subscribers and they depend on a single publisher and when any data or state changes, the subscribers get notified. Here we have one publisher and many subscribers. So the relationship between publisher and subscriber is one-to-many.
The observer pattern defines the one-to-many relationship between a set of objects, when the state of one object changes, all of its dependents are notified.
The class digram:
领英推荐
Concrete subject (publisher) always implements the subject interface. Concrete subject also implements the notify method to acknowledge the observers when any changes happens.
All observers need to implement the observer interface. The update method gets called when the subject's state changes. Concrete observer can be any class. Each concrete observer is registered to a concrete subject.
Observer Design Pattern implementation in Python:
from abc import ABC, abstractmethod
class SubjectInterface(ABC):
@abstractmethod
def register(self, observer_obj):
pass
@abstractmethod
def remove(self, observer_obj):
pass
def notify(self):
pass
class ConcreteSubject(SubjectInterface):
data = 0.00
def __init__(self) -> None:
super().__init__()
self.observers = list()
def register(self, observer_obj):
self.observers.append(observer_obj)
def remove(self, observer_obj):
self.observers.remove(observer_obj)
def notify(self):
for observer_obj in self.observers:
observer_obj.update(self.data)
from abc import ABC, abstractmethod
class ObserverInterface(ABC):
@abstractmethod
def update(self, data):
pass
class ConcreteObserver1(ObserverInterface):
def update(self, data):
# do something with this data
pass
class ConcreteObserver2(ObserverInterface):
def update(self, data):
# do something with this data
pass
References: