Skip to content

Latest commit

 

History

History
91 lines (65 loc) · 3.17 KB

File metadata and controls

91 lines (65 loc) · 3.17 KB

Observer Design Pattern

Watchful Eyes, Timely Updates, A Symphony of Awareness

In essence, the Observer Design Pattern transforms your code into a buzzing newsroom, where objects stay tuned for the latest updates, reacting with agility and awareness to any changes in their surroundings. This promotes decoupled communication, efficient updates, and a dynamic ecosystem of informed objects.


Workflow

  1. Define an interface for the "observer". This specifies the method for receiving updates about the subject's state changes.
  2. Concrete objects implement the observer interface. These are the "reporters" who register their interest in the subject.
  3. The "subject" object maintains a list of registered observers. It's the "news source" that triggers notifications when its state changes.
  4. When the subject's state changes, it notifies all registered observers. This is the "press release" moment, delivering updates to interested parties.
  5. Observers receive the notification and can react accordingly. They update their own state or perform actions based on the received information.

Benefits

  • Decoupling Subjects and observers are loosely coupled, making them independent and easier to maintain.
  • Flexibility New observers can be easily added or removed without affecting the subject or other observers.
  • Reduced code duplication Instead of manually checking for updates, observers rely on the subject's notifications.
  • Efficient communication Updates are sent only to interested parties, minimizing unnecessary processing.

Example

from abc import ABC, abstractmethod

class PostSubject(ABC):
    @abstractmethod
    def register_observer(self, observer):
        pass

    @abstractmethod
    def remove_observer(self, observer):
        pass

    @abstractmethod
    def notify_observers(self):
        pass

class Observer(ABC):
    @abstractmethod
    def update(self, subject, *args, **kwargs):
        pass

class BlogPost(PostSubject):
    def __init__(self, title, author):
        self.title = title
        self.author = author
        self.readers = []

    def register_observer(self, reader):
        self.readers.append(reader)

    def remove_observer(self, reader):
        self.readers.remove(reader)

    def notify_observers(self):
        for reader in self.readers:
            reader.update(self)

    def publish(self):
        print(f"Author '{self.author}' published a new post: '{self.title}'")
        self.notify_observers()

class AuthorDashboard(Observer):
    def update(self, subject):
        print("Author dashboard: Your post has been published!")

class ReaderNotification(Observer):
    def update(self, subject):
        print(f"Reader notification: New post by '{subject.author}': '{subject.title}'")

Remember

  • Use the Observer pattern when objects need to stay informed about the state of another object, but shouldn't directly access its internal state.
  • Overuse can lead to complex notification hierarchies for simple updates and unnecessary overhead for trivial changes.
  • Clearly define the responsibilities of the subject and the observers, and ensure efficient notification mechanisms are used.