Sobes.tech
Middle
107
questionbank

Что такое паттерн проектирования 'Наблюдатель' (Observer)?

Ответ от нейросети

sobes.tech AI

Паттерн проектирования "Наблюдатель" (Observer) — это поведенческий паттерн, который определяет зависимость типа "один ко многим" между объектами.

Основная идея: когда состояние одного объекта (издателя/субъекта) изменяется, все зависимые от него объекты (наблюдатели/подписчики) автоматически получают уведомление об этом и обновляются.

Компоненты паттерна:

  • Издатель (Subject/Observable): Объект, состояние которого может меняться. Он содержит список своих наблюдателей и предоставляет методы для их регистрации (подписки), отмены регистрации (отписки) и уведомления.
  • Наблюдатель (Observer): Объект, который зависит от состояния Издателя. Он предоставляет метод update(), который вызывается Издателем при изменении его состояния.
  • Конкретный Издатель (Concrete Subject): Конкретная реализация Издателя. Содержит данные, которые интересны наблюдателям. При изменении этих данных, он вызывает метод уведомления.
  • Конкретный Наблюдатель (Concrete Observer): Конкретная реализация Наблюдателя. Реализует метод update() для выполнения определенных действий в ответ на уведомление от Издателя.

Принцип работы:

  1. Наблюдатели регистрируются у Издателя, выражая интерес к его состоянию.
  2. Когда состояние Издателя меняется, он проходит по списку зарегистрированных наблюдателей.
  3. Издатель вызывает метод update() каждого наблюдателя, передавая, при необходимости, информацию об изменении.
  4. Наблюдатели обрабатывают полученное уведомление.

Применение в 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