#include <iostream>
#include <vector>
#include <string>
#include <memory>

// Forward declaration of Subject
class Subject;

// Observer interface
class Observer {
public:
    virtual ~Observer() = default;
    virtual void update(const std::string& message_from_subject) = 0;
};

// ConcreteObserver implementation
class ConcreteObserver : public Observer {
private:
    std::string name_;
    std::string message_from_subject_;
    Subject& subject_;

public:
    ConcreteObserver(const std::string& name, Subject& subject) : name_(name), subject_(subject) {}
    
    void update(const std::string& message_from_subject) override {
        message_from_subject_ = message_from_subject;
        display();
    }

    void display() const {
        std::cout << "Observer " << name_ << " received message: " << message_from_subject_ << std::endl;
    }
};

// Subject class
class Subject {
private:
    std::vector<std::weak_ptr<Observer>> observers_;
    std::string message_;

public:
    void addObserver(std::shared_ptr<Observer> observer) {
        observers_.push_back(observer);
    }

    void removeObserver(std::shared_ptr<Observer> observer) {
        observers_.erase(std::remove_if(observers_.begin(), observers_.end(),
            [&observer](const std::weak_ptr<Observer>& o) {
                return o.lock() == observer;
            }), observers_.end());
    }

    void notify() {
        for (auto& weak_observer : observers_) {
            if (auto observer = weak_observer.lock()) {
                observer->update(message_);
            }
        }
    }

    void createMessage(const std::string& message) {
        message_ = message;
        notify();
    }
};

int main() {
    Subject subject;
    
    auto observer1 = std::make_shared<ConcreteObserver>("Observer 1", subject);
    auto observer2 = std::make_shared<ConcreteObserver>("Observer 2", subject);
    
    subject.addObserver(observer1);
    subject.addObserver(observer2);
    
    subject.createMessage("Hello Observers!");
    
    subject.removeObserver(observer1);
    
    subject.createMessage("Hello Observer 2!");
    
    return 0;
}

Last modified: Sunday, 30 June 2024, 7:10 PM