Problem Statement
When multiple parts of a system need to stay updated about changes in another part, manually notifying each part leads to tightly coupled code and missed updates. This causes bugs and makes the system hard to maintain or extend.
Jump into concepts and practice - no test required
This diagram shows a Subject holding references to multiple Observers. Observers register to the Subject, and when the Subject's state changes, it notifies all registered Observers.
### Before: Without Observer Pattern class Subject: def __init__(self): self.state = None self.observer1 = None self.observer2 = None def set_state(self, state): self.state = state if self.observer1: self.observer1.update(state) if self.observer2: self.observer2.update(state) class Observer1: def update(self, state): print(f"Observer1: State updated to {state}") class Observer2: def update(self, state): print(f"Observer2: State updated to {state}") subject = Subject() subject.observer1 = Observer1() subject.observer2 = Observer2() subject.set_state('ON') ### After: With Observer Pattern class Subject: def __init__(self): self._observers = [] self._state = None def register(self, observer): self._observers.append(observer) def unregister(self, observer): self._observers.remove(observer) def notify(self): for observer in self._observers: observer.update(self._state) def set_state(self, state): self._state = state self.notify() class Observer: def update(self, state): print(f"Observer: State updated to {state}") subject = Subject() observer1 = Observer() observer2 = Observer() subject.register(observer1) subject.register(observer2) subject.set_state('ON')
What is the main purpose of the Observer pattern in system design?
Which of the following is the correct way to register an observer in the Observer pattern?
subject = Subject()
observer = ConcreteObserver()
# What code registers the observer?attach or addObserver to register observers.addObserver is used in some languages, attach is the classic and widely accepted method name.Given this code snippet, what will be printed?
class Subject:
def __init__(self):
self.observers = []
self.state = 0
def attach(self, observer):
self.observers.append(observer)
def set_state(self, state):
self.state = state
for obs in self.observers:
obs.update(state)
class Observer:
def __init__(self, name):
self.name = name
def update(self, state):
print(f"{self.name} received state {state}")
subject = Subject()
obs1 = Observer('A')
obs2 = Observer('B')
subject.attach(obs1)
subject.attach(obs2)
subject.set_state(5)set_state(5) is called, it updates the state and calls update(5) on each observer.Identify the bug in this Observer pattern implementation:
class Subject:
def __init__(self):
self.observers = set()
def attach(self, observer):
self.observers.add(observer)
def notify(self):
for obs in self.observers:
obs.update()
class Observer:
def update(self, state):
print(f"State updated to {state}")
subject = Subject()
obs = Observer()
subject.attach(obs)
subject.notify()update method expects a state argument, but notify calls update() without any argument.You are designing a stock price alert system using the Observer pattern. Multiple clients want updates only when the stock price changes by more than 5%. How should you modify the Observer pattern to handle this efficiently?