Наблюдатель (Observer) :: Cетевой уголок Majestio

Наблюдатель (Observer)


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

Применимость

Подробнее на 👉 refactoring.guru

UML-диаграмма

Пример реализации

#include <algorithm>
#include <iostream>
#include <vector>

// Интерфейс наблюдателя

class Subscriber {
 public:
  virtual void update(const std::string& message) = 0;
};

// Издатель

class Publisher {
 private:
  std::vector<Subscriber*> subscribers;
  std::string message;

 public:
  void subscribe(Subscriber* subscriber) { subscribers.push_back(subscriber); }

  void unsubscribe(Subscriber* subscriber) {
    subscribers.erase(
        std::remove(subscribers.begin(), subscribers.end(), subscriber),
        subscribers.end());
  }

  void setMessage(const std::string& newMessage) {
    message = newMessage;
    notifySubscribers();
  }

 private:
  void notifySubscribers() {
    for (Subscriber* subscriber : subscribers) {
      subscriber->update(message);
    }
  }
};

// Конкретный наблюдатель 1

class ConcreteSubscriber1 : public Subscriber {
 public:
  void update(const std::string& message) override {
    std::cout << "Наблюдатель 1 получил сообщение: " << message << std::endl;
    // Здесь можно добавить логику реакции на сообщение
  }
};

// Конкретный наблюдатель 2

class ConcreteSubscriber2 : public Subscriber {
 public:
  void update(const std::string& message) override {
    std::cout << "Наблюдатель 2 получил сообщение: " << message << std::endl;
    // Здесь можно добавить логику реакции на сообщение
  }
};

int main() {
  Publisher publisher;

  ConcreteSubscriber1 subscriber1;
  publisher.subscribe(&subscriber1);
  ConcreteSubscriber2 subscriber2;
  publisher.subscribe(&subscriber2);
  publisher.setMessage("Новый автомобиль построен!");
  publisher.unsubscribe(&subscriber1);
  publisher.setMessage("Новый двигатель установлен!");

  return 0;
}
Будет напечатано:
Наблюдатель 1 получил сообщение: Новый автомобиль построен!
Наблюдатель 2 получил сообщение: Новый автомобиль построен!
Наблюдатель 2 получил сообщение: Новый двигатель установлен!
abstract class Subscriber {
  void update(String message);
}

class Publisher {
  List<Subscriber> _subscribers = [];
  String _message = '';

  void subscribe(Subscriber subscriber) {
    _subscribers.add(subscriber);
  }

  void unsubscribe(Subscriber subscriber) {
    _subscribers.remove(subscriber);
  }

  void setMessage(String newMessage) {
    _message = newMessage;
    notifySubscribers();
  }

  void notifySubscribers() {
    for (Subscriber subscriber in _subscribers) {
      subscriber.update(_message);
    }
  }
}

class ConcreteSubscriber1 implements Subscriber {
  void update(String message) {
    print('Наблюдатель 1 получил сообщение: $message');
    // Здесь можно добавить логику реакции на сообщение
  }
}

class ConcreteSubscriber2 implements Subscriber {
  void update(String message) {
    print('Наблюдатель 2 получил сообщение: $message');
    // Здесь можно добавить логику реакции на сообщение
  }
}

void main() {
  var publisher = Publisher();
  var subscriber1 = ConcreteSubscriber1();
  publisher.subscribe(subscriber1);
  var subscriber2 = ConcreteSubscriber2();
  publisher.subscribe(subscriber2);
  publisher.setMessage('Новый автомобиль построен!');
  publisher.unsubscribe(subscriber1);
  publisher.setMessage('Новый двигатель установлен!');
}
Будет напечатано:
Наблюдатель 1 получил сообщение: Новый автомобиль построен!
Наблюдатель 2 получил сообщение: Новый автомобиль построен!
Наблюдатель 2 получил сообщение: Новый двигатель установлен!
Рейтинг: 0/5 - 0 голосов