Observer#
The Observer is a behavioral design pattern that allows some objects to notify other objects about changes in their state. The Observer pattern provides a way to subscribe and unsubscribe to and from these notifications for multiple objects.
UML Diagram#
+-------------------+ +-------------------+
| Subject |<-------| ConcreteSubject |
|-------------------| |-------------------|
| +attach(observer) | | +attach(observer) |
| +detach(observer) | | +detach(observer) |
| +notify() | | +notify() |
+-------------------+ +-------------------+
^ ^
| |
+-------------------+ +-------------------+
| Observer | | ConcreteObserver |
|-------------------| |-------------------|
| +update(state) | | +update(state) |
+-------------------+ +-------------------+
In this diagram, Subject is an interface with methods attach(observer), detach(observer), and notify(). Observer is an interface with the method update(state). ConcreteSubject and ConcreteObserver are classes that implement the Subject and Observer interfaces, respectively. The arrows indicate that the ConcreteSubject and ConcreteObserver classes inherit from the Subject and Observer interfaces.
Java Example#
import java.util.ArrayList;
import java.util.List;
public interface Observer {
void update(String state);
}
public interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
}
public class ConcreteObserver implements Observer {
@Override
public void update(String state) {
System.out.println("State changed: " + state);
}
}
Python Example#
from __future__ import annotations
from abc import ABC, abstractmethod
class Observer(ABC):
@abstractmethod
def update(self, state: str) -> None:
pass
class Subject(ABC):
@abstractmethod
def attach(self, observer: Observer) -> None:
pass
@abstractmethod
def detach(self, observer: Observer) -> None:
pass
@abstractmethod
def notify(self) -> None:
pass
class ConcreteSubject(Subject):
_state: str = None
_observers: list[Observer] = []
def attach(self, observer: Observer) -> None:
self._observers.append(observer)
def detach(self, observer: Observer) -> None:
self._observers.remove(observer)
def notify(self) -> None:
for observer in self._observers:
observer.update(self._state)
def set_state(self, state: str) -> None:
self._state = state
self.notify()
class ConcreteObserver(Observer):
def update(self, state: str) -> None:
print(f"State changed: {state}")