Что такое паттерн Observer

Ответ

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

Основные компоненты:

  • Subject (издатель) — хранит список подписчиков, умеет добавлять/удалять их и оповещать о событиях.
  • Observer (подписчик) — интерфейс с методом update(), который вызывается при изменении состояния издателя.

Пример на Kotlin:

interface Observer {
    fun update(data: String)
}

class Subject {
    private val observers = mutableListOf<Observer>()

    fun addObserver(observer: Observer) {
        observers.add(observer)
    }

    fun notifyObservers(data: String) {
        observers.forEach { it.update(data) }
    }
}

class ConcreteObserver : Observer {
    override fun update(data: String) {
        println("Received: $data")
    }
}

Использование:

val subject = Subject()
subject.addObserver(ConcreteObserver())
subject.notifyObservers("Hello!") // Выведет: "Received: Hello!"

Где применяется: LiveData, RxJava, BroadcastReceiver.

Ответ 18+ 🔞

Давай разберём эту штуку, а то звучит как какая-то хитрая жопа, а на деле всё проще пареной репы. Паттерн Observer, или Наблюдатель — это такой способ сказать одним объектам: «Эй, чуваки, когда у меня тут что-то поменяется, я вас всех оповещу, чтобы вы не спали».

Кто тут главный по тарелочкам:

  • Subject (Издатель, он же инициатор) — этот тип в центре внимания. У него есть список всех, кто на него подписан, как в паблике. Он умеет добавлять подписчиков, удалять заскучавших и главное — орать на всю деревню (вызывать метод), когда у него что-то случилось.
  • Observer (Подписчик, он же Наблюдатель) — это интерфейс, типа договор: «У тебя будет метод update(), и когда издатель крикнет, ты его вызовешь и сделаешь что надо». Каждый подписчик реализует эту фигню по-своему.

Смотри, как это выглядит в коде на Kotlin:

interface Observer {
    fun update(data: String) // Подписчик, будь добр, имей такой метод. Договорились?
}

class Subject {
    private val observers = mutableListOf<Observer>() // Список подписчиков. Пока пустой.

    fun addObserver(observer: Observer) {
        observers.add(observer) // О, новый подписчик! Добавили в список.
    }

    fun notifyObservers(data: String) {
        observers.forEach { it.update(data) } // ВАЖНОЕ СОБЫТИЕ! Бежим по списку и тыкаем каждого методом update.
    }
}

class ConcreteObserver : Observer {
    override fun update(data: String) {
        println("Received: $data") // А вот что делает конкретный подписчик, когда его оповестили. Например, печатает.
    }
}

Как это запустить в дело:

val subject = Subject() // Создали нашего главного крикуна.
subject.addObserver(ConcreteObserver()) // Подписали на него одного внимательного товарища.
subject.notifyObservers("Hello!") // Издатель говорит: "Внимание, событие!".
// Подписчик срабатывает и выводит: "Received: Hello!"

Где эту дичь можно встретить вживую? Да везде! Тот же LiveData в Android — чистейший Observer, он же тебе и RxJava с его подписками, и BroadcastReceiver. Вся суть в том, чтобы не дергать кого-то каждую секунду с вопросом «Ну чё там?», а спокойно ждать, когда тебе самому сообщат важные новости. Удобно, ёпта.