Observer Design Pattern

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.

No alt text provided for this image

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:

No alt text provided for this image

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:

  1. https://refactoring.guru/design-patterns/observer
  2. https://www.geeksforgeeks.org/observer-pattern-set-1-introduction/
  3. https://www.tutorialspoint.com/design_pattern/observer_pattern.htm


要查看或添加评论,请登录

Md Imran Sheikh的更多文章

社区洞察

其他会员也浏览了