Skip to content

Design Patterns: Observer Pattern

Published: at 04:40 PM

The Observer pattern is a widely used design pattern in software engineering that allows objects to subscribe to changes in state or behavior of another object. It falls under the category of behavioral patterns in computer science. In this blog post, we will explore the Observer pattern in detail and its implementation in Python.

Overview of the Observer Pattern

The Observer pattern defines a one-to-many relationship between objects, where multiple objects (observers) are notified and updated when the state or behavior of a subject (observable) changes. The observable maintains a list of its observers and notifies them automatically when any changes occur. This pattern is used to promote loose coupling between objects and makes the code more modular and extensible.

Components of the Observer Pattern

The Observer pattern consists of four main components:

Implementation of the Observer Pattern in Python

To implement the Observer pattern in Python, we will create a Subject interface and an Observer interface. We will then create a ConcreteSubject class that will implement the Subject interface and a ConcreteObserver class that will implement the Observer interface.

Subject interface

from abc import ABC, abstractmethod

class Subject(ABC):
    @abstractmethod
    def attach(self, observer):
        pass

    @abstractmethod
    def detach(self, observer):
        pass

    @abstractmethod
    def notify(self):
        pass

Observer interface

from abc import ABC, abstractmethod

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

ConcreteSubject interface

class ConcreteSubject(Subject):
    def __init__(self):
        self.observers = []

    def attach(self, observer):
        self.observers.append(observer)

    def detach(self, observer):
        self.observers.remove(observer)

    def notify(self):
        for observer in self.observers:
            observer.update(self)

ConcreteObserver interface

class ConcreteObserver(Observer):
    def update(self, subject):
        print("Subject state changed!")

Example usage of the Observer pattern:

subject = ConcreteSubject()
observer = ConcreteObserver()

subject.attach(observer)
subject.notify()

subject.detach(observer)
subject.notify()

In this example, we create a ConcreteSubject object and a ConcreteObserver object. We attach the observer to the subject and notify the observer of any changes in the subject’s state. We then detach the observer from the subject and notify it again.

Advantages of using the Observer Pattern

The Observer pattern has the following advantages:

Disadvantages of using the Observer Pattern

The Observer pattern has the following disadvantages:

When to use the Observer Pattern

The Observer pattern is useful when:

Conclusion

In conclusion, the Observer pattern is a useful design pattern that allows objects to subscribe to changes in the state or behavior of another object. It promotes loose coupling between objects, making the code more modular and extensible. In this blog post, we have discussed the components of the Observer pattern and its implementation in Python. We have also discussed the advantages and disadvantages of using the Observer pattern and when it is appropriate to use it. By using the Observer pattern, we can design systems that are more modular, flexible, and easier to maintain.