Паттерн Наблюдатель является поведенческим паттерном проектирования. Он предназначен для организации взаимодействия между классами. Он реализует взаимодействия типа один-много, при котором множество объектов получают информацию об изменениях основного объекта.
По данному принципу работает огромное количество приложений. Это могут быть новостные рассылки, уведомления от приложений на смартфонах, автоматическая рассылка почты, системы достижений в израх и многое другое.
Вместо решения, при котором объект наблюдатель опрашивает наблюдаемый объект о произошедших изменениях, наблюдаймый объект самостоятельно уведомляет о них наблюдателя.
В паттерне наблюдатель в наблюдаемой системе должен быть имплементирован интерфейс наблюдаемого объекта, позволяющий "подписывать" пользователя на обновления объекта и отправлять всем подписанным пользователям уведомления об изменениях. Также должны существовать наблюдатели, реализующие интерфейс наблюдателя.
Для паттерна Observer необходимы следующие классы:
У наблюдаемого объекта должны быть реализованы методы:
У наблюдателя должен быть реализован метод update, который будет вызван наблюдаемым объектом при обновлении.
При использовании паттерна Наблюдатель создаются наблюдатели и система. Для использования паттерна наблюдатель подписывается на обновления системы. При изменениях система оповещает об изменениях всех текущих подписчиков при помощи вызова у подписчиков метода update.
from abc import ABC, abstractmethod
class NotificationManager: # Наблюдаемая система
def __init__(self):
self.__subscribers = set() # При инициализации множество подписчиков звдвется пустым
def subscribe(self, subscriber):
self.__subscribers.add(subscriber) # Для того чтобы подмисать пользователя, он добавляется во множество подписчиков
def unsubcribe(self, subscriber):
self.__subscribers.remove(subscriber) # Удаление подписчика из списка
def notify(self, message):
for subscriber in self.__subscribers:
subscriber.update(message) # Отправка уведомления всем подписчикам
class AbstractObserver(ABC):
@abstractmethod
def update(self, message): # Абстрактный наблюдатель задает метод update
pass
class MessageNotifier(AbstractObserver):
def __init__(self, name):
self.__name = name
def update(self, message): # Конкретная реализация метода update
print(f'{self.__name} recieved message!')
class MessagePrinter(AbstractObserver):
def __init__(self, name):
self.__name = name
def update(self, message): # Конкретная реализация метода update
print(f'{self.__name} recieved message: {message}')
notifier1 = MessageNotifier("Notifier1")
printer1 = MessagePrinter("Printer1")
printer2 = MessagePrinter("Printer2")
manager = NotificationManager()
manager.subscribe(notifier1)
manager.subscribe(printer1)
manager.subscribe(printer2)
manager.notify("Hi!")
Printer2 recieved message: Hi! Printer1 recieved message: Hi! Notifier1 recieved message!