3.8 KiB
obj |
---|
concept |
Observer Pattern
Description:
The Observer Pattern is a behavioral design pattern that defines a one-to-many dependency between objects so that when one object (the subject) changes state, all its dependents (observers) are notified and updated automatically. It's used to establish dynamic, distributed, and loosely coupled communication between objects, making it easy to maintain consistency and synchronization.
How it's Used:
- Subject Interface: Define a subject interface or abstract class that declares methods for attaching, detaching, and notifying observers. It should also have a method to update its state.
- Concrete Subject: Create a concrete subject class that implements the subject interface. This class maintains a list of its observers and notifies them when its state changes.
- Observer Interface: Define an observer interface with an update method that subjects will call to notify observers of changes.
- Concrete Observer: Create concrete observer classes that implement the observer interface. These classes define how they respond to updates from the subject.
- Client Code: In client code, create instances of concrete subjects and observers, attach observers to subjects, and let the system handle the rest of the communication.
Example: Let's create an example of the Observer Pattern in Python to model a simple weather monitoring system where weather stations act as subjects and display panels act as observers.
from abc import ABC, abstractmethod
# Step 1: Subject Interface
class Subject(ABC):
@abstractmethod
def attach(self, observer):
pass
@abstractmethod
def detach(self, observer):
pass
@abstractmethod
def notify(self):
pass
# Step 2: Concrete Subject (WeatherStation)
class WeatherStation(Subject):
def __init__(self):
self.observers = []
self.temperature = 0.0
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.temperature)
def set_temperature(self, temperature):
self.temperature = temperature
self.notify()
# Step 3: Observer Interface
class Observer(ABC):
@abstractmethod
def update(self, temperature):
pass
# Step 4: Concrete Observer (DisplayPanel)
class DisplayPanel(Observer):
def __init__(self, name):
self.name = name
def update(self, temperature):
print(f"{self.name} Display: Temperature is {temperature}°C")
# Step 5: Client Code
def main():
weather_station = WeatherStation()
panel1 = DisplayPanel("Panel 1")
panel2 = DisplayPanel("Panel 2")
weather_station.attach(panel1)
weather_station.attach(panel2)
weather_station.set_temperature(25.5)
weather_station.set_temperature(30.0)
if __name__ == "__main__":
main()
In this Python example, we define a Subject
interface (Step 1) with attach
, detach
, and notify
methods. The WeatherStation
class (Step 2) implements the subject interface, maintains a list of observers, and notifies them when the temperature changes.
We also define an Observer
interface (Step 3) with an update
method. The DisplayPanel
class (Step 4) implements the observer interface and defines how it responds to updates.
In the main
function (Step 5), we create a weather station and two display panels. We attach the display panels to the weather station, and when the weather station's temperature changes, it automatically notifies the attached display panels to update their displays. This allows for real-time synchronization between the weather station and the display panels.