Source code for Behavioral.Observer.python.observer

from typing import List, Protocol
import logging

# Setup logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("observer")


[docs] class Observer(Protocol): """ Interface for observers that listen for updates from a subject. """
[docs] def update(self, state: str) -> None: """ Called by the subject to notify the observer of a state change. :param state: The updated state. """ pass
[docs] class Subject: """ Manages observers and notifies them of state changes. """
[docs] def __init__(self): """ Initialize the Subject with an empty list of observers and a default state. """ self._observers: List[Observer] = [] self._state: str = ""
[docs] def attach(self, observer: Observer) -> None: """ Add an observer to the subject. :param observer: The observer to attach. """ if observer not in self._observers: self._observers.append(observer) logger.info("Attached observer: %s", observer)
[docs] def detach(self, observer: Observer) -> None: """ Remove an observer from the subject. :param observer: The observer to detach. """ if observer in self._observers: self._observers.remove(observer) logger.info("Detached observer: %s", observer)
[docs] def notify(self) -> None: """ Notify all attached observers of the current state. """ for observer in self._observers: observer.update(self._state)
[docs] def set_state(self, state: str) -> None: """ Update the subject's state and notify observers. :param state: The new state to set. """ self._state = state logger.info("Subject state updated to: %s", state) self.notify()
[docs] def get_state(self) -> str: """ Retrieve the current state of the subject. :return: The current state. """ return self._state
[docs] class ConcreteObserver: """ Concrete implementation of an observer. """
[docs] def __init__(self, name: str): """ Initialize the concrete observer with a given name. :param name: The name of the observer. """ self.name = name
[docs] def update(self, state: str) -> None: """ Receive an update from the subject. :param state: The updated state. """ logger.info("Observer %s received update. New state: %s", self.name, state)
def __str__(self) -> str: """ String representation of the observer. :return: Observer's name. """ return self.name