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

Ответ

Observer — это поведенческий шаблон проектирования, который определяет отношение «один-ко-многим» между объектами. Когда состояние одного объекта (Субъекта) меняется, все зависимые от него объекты (Наблюдатели) автоматически уведомляются и обновляются.

Ключевые компоненты:

  • Subject (Субъект/Издатель): Содержит список наблюдателей и предоставляет методы для их добавления (attach), удаления (detach) и уведомления (notify).
  • Observer (Наблюдатель/Подписчик): Определяет интерфейс с методом обновления (например, update()), который вызывается субъектом.
  • ConcreteSubject & ConcreteObserver: Конкретные реализации.

Пример на Java:

// Интерфейс Наблюдателя
interface Observer {
    void update(String stockSymbol, double stockPrice);
}

// Конкретный Субъект (Биржевой тикер)
class StockTicker {
    private String symbol;
    private double price;
    private List<Observer> investors = new ArrayList<>();

    public void setPrice(double price) {
        this.price = price;
        notifyObservers(); // Критический шаг: уведомляем всех при изменении
    }

    public void attach(Observer o) { investors.add(o); }
    public void detach(Observer o) { investors.remove(o); }

    private void notifyObservers() {
        for (Observer investor : investors) {
            investor.update(symbol, price);
        }
    }
}

// Конкретный Наблюдатель
class Investor implements Observer {
    private String name;
    public Investor(String name) { this.name = name; }

    @Override
    public void update(String symbol, double price) {
        System.out.printf("Инвестор %s: Акция %s теперь стоит $%.2f%n", name, symbol, price);
    }
}

// Использование
StockTicker appleStock = new StockTicker("AAPL", 150.0);
Investor alice = new Investor("Alice");
Investor bob = new Investor("Bob");

appleStock.attach(alice);
appleStock.attach(bob);

appleStock.setPrice(155.5);
// Вывод:
// Инвестор Alice: Акция AAPL теперь стоит $155.50
// Инвестор Bob: Акция AAPL теперь стоит $155.50

Применение: Системы событий в GUI, реактивное программирование (RxJava), модель MVC, уведомления в микросервисах.

Ответ 18+ 🔞

Вот, представляешь, есть такая штука — Observer. Это, блядь, не какой-нибудь подглядыватель в замочную скважину, а целый поведенческий паттерн. Суть его проще пареной репы, но гениальная, ёпта. Один объект (Субъект) — такой себе царь и бог — меняет своё состояние, а все, кто на него подписался (Наблюдатели), тут же получают пиздюлину в виде уведомления и бегут обновляться. Отношения «один-ко-многим», мать их.

Кто есть кто в этой пьесе:

  • Субъект (Subject/Издатель): Этот гад держит список всех своих подписчиков-лоботрясов. У него три священных метода: добавить лоботряса (attach), выгнать лоботряса (detach) и орать на всех сразу — «Я ИЗМЕНИЛСЯ!» (notify).
  • Наблюдатель (Observer/Подписчик): Просто интерфейс с одним методом, обычно update(). Его реализуют все, кто хочет знать, когда царь-субъект чихнул.
  • Конкретные ребята (ConcreteSubject & ConcreteObserver): Ну, обычные смертные реализации этих интерфейсов.

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

// Интерфейс Наблюдателя. Говорит: "Хочешь следить — реализуй метод update, мудак".
interface Observer {
    void update(String stockSymbol, double stockPrice);
}

// Конкретный Субъект — биржевой тикер. Настоящая сука с характером.
class StockTicker {
    private String symbol;
    private double price;
    private List<Observer> investors = new ArrayList<>(); // Список лохов, пардон, инвесторов.

    // Вот тут магия! Меняем цену — и сразу всех трогаем.
    public void setPrice(double price) {
        this.price = price;
        notifyObservers(); // Критический шаг: орем на всю деревню!
    }

    public void attach(Observer o) { investors.add(o); } // Присоединился к секте.
    public void detach(Observer o) { investors.remove(o); } // Слинял, тварь.

    // А вот и сам ор! Пробегаемся по списку и тычем каждого носом в новую цену.
    private void notifyObservers() {
        for (Observer investor : investors) {
            investor.update(symbol, price);
        }
    }
}

// Конкретный Наблюдатель — инвестор. Сидит и ждёт, когда его ткнут.
class Investor implements Observer {
    private String name;
    public Investor(String name) { this.name = name; }

    @Override
    public void update(String symbol, double price) {
        // Получил пинка — выдал реакцию.
        System.out.printf("Инвестор %s: Акция %s теперь стоит $%.2f%n", name, symbol, price);
    }
}

// А теперь сценарий, блядь!
StockTicker appleStock = new StockTicker("AAPL", 150.0);
Investor alice = new Investor("Alice"); // Алиса
Investor bob = new Investor("Bob");     // Боб, пидарас шерстяной

appleStock.attach(alice); // Алиса подписалась на боль
appleStock.attach(bob);   // Боб тоже

appleStock.setPrice(155.5); // БАЦ! Цена поплыла!
// И тут же на экране:
// Инвестор Alice: Акция AAPL теперь стоит $155.50
// Инвестор Bob: Акция AAPL теперь стоит $155.50

Где эту хуйню применяют? Да везде! Все эти системы событий в интерфейсах, реактивное программирование (этот ваш RxJava), модель MVC (где View — тот ещё подглядыватель за Model), да даже уведомления между микросервисами — всё это, блядь, Observer, просто в разных париках и с разным макияжем.