Middle
107
questionbank
Что такое паттерн проектирования 'Наблюдатель' (Observer)?
Ответ от нейросети
sobes.tech AI
Паттерн проектирования "Наблюдатель" (Observer) — это поведенческий паттерн, который определяет зависимость типа "один ко многим" между объектами.
Основная идея: когда состояние одного объекта (издателя/субъекта) изменяется, все зависимые от него объекты (наблюдатели/подписчики) автоматически получают уведомление об этом и обновляются.
Компоненты паттерна:
- Издатель (Subject/Observable): Объект, состояние которого может меняться. Он содержит список своих наблюдателей и предоставляет методы для их регистрации (подписки), отмены регистрации (отписки) и уведомления.
- Наблюдатель (Observer): Объект, который зависит от состояния Издателя. Он предоставляет метод
update(), который вызывается Издателем при изменении его состояния. - Конкретный Издатель (Concrete Subject): Конкретная реализация Издателя. Содержит данные, которые интересны наблюдателям. При изменении этих данных, он вызывает метод уведомления.
- Конкретный Наблюдатель (Concrete Observer): Конкретная реализация Наблюдателя. Реализует метод
update()для выполнения определенных действий в ответ на уведомление от Издателя.
Принцип работы:
- Наблюдатели регистрируются у Издателя, выражая интерес к его состоянию.
- Когда состояние Издателя меняется, он проходит по списку зарегистрированных наблюдателей.
- Издатель вызывает метод
update()каждого наблюдателя, передавая, при необходимости, информацию об изменении. - Наблюдатели обрабатывают полученное уведомление.
Применение в QA Automation:
- Мониторинг состояния UI-элементов или процессов.
- Отслеживание изменений в логах или файлах конфигурации.
- Реализация событийной модели для взаимодействия между различными частями фреймворка автоматизации.
Преимущества:
- Слабая связанность между Издателем и Наблюдателями.
- Возможность добавления/удаления наблюдателей динамически.
- Поддержка принципа "один ко многим" уведомлений.
Недостатки:
- Неожиданные обновления у наблюдателей, если издатель уведомляет слишком часто или без четкой логики.
- Порядок уведомления наблюдателей не гарантирован, если это не предусмотрено реализацией.
Пример (Python):
class Subject:
def __init__(self):
self._observers = []
self._state = None
def attach(self, observer):
# Добавляет наблюдателя
self._observers.append(observer)
def detach(self, observer):
# Удаляет наблюдателя
try:
self._observers.remove(observer)
except ValueError:
pass # Наблюдатель не найден
def notify(self):
# Уведомляет всех наблюдателей
for observer in self._observers:
observer.update(self._state)
@property
def state(self):
# Геттер для состояния
return self._state
@state.setter
def state(self, new_state):
# Сеттер для состояния, вызывает уведомление
print(f"Subject: Changing state to {new_state}")
self._state = new_state
self.notify()
class Observer:
def update(self, state):
# Метод обновления для наблюдателя
pass
class ConcreteObserverA(Observer):
def update(self, state):
# Конкретная реализация обновления для наблюдателя A
print(f"ConcreteObserverA: Subject state is {state}")
class ConcreteObserverB(Observer):
def update(self, state):
# Конкретная реализация обновления для наблюдателя B
if state >= 0:
print(f"ConcreteObserverB: Subject state changed to a positive value: {state}")
# Использование паттерна
subject = Subject()
observer_a = ConcreteObserverA()
observer_b = ConcreteObserverB()
subject.attach(observer_a)
subject.attach(observer_b)
subject.state = 10
subject.state = -5
subject.detach(observer_b)
subject.state = 25