#include <iostream>
#include <vector>
#include <algorithm>
#include <memory>
#include <mutex>// 觀察者接口
class IObserver {
public:virtual ~IObserver() = default;virtual void update(const std::string& message) = 0;
};// 主題接口
class ISubject {
public:virtual ~ISubject() = default;virtual void attach(std::shared_ptr<IObserver> observer) = 0;virtual void detach(std::shared_ptr<IObserver> observer) = 0;virtual void notify(const std::string& message) = 0;
};// 具體主題實現
class ConcreteSubject : public ISubject {
private:std::vector<std::shared_ptr<IObserver>> observers_;std::mutex mutex_;std::string state_;public:void attach(std::shared_ptr<IObserver> observer) override {std::lock_guard<std::mutex> lock(mutex_);observers_.push_back(observer);}void detach(std::shared_ptr<IObserver> observer) override {std::lock_guard<std::mutex> lock(mutex_);observers_.erase(std::remove(observers_.begin(), observers_.end(), observer),observers_.end());}void notify(const std::string& message) override {std::vector<std::shared_ptr<IObserver>> observers_copy;{std::lock_guard<std::mutex> lock(mutex_);observers_copy = observers_;}for (auto& observer : observers_copy) {observer->update(message);}}void setState(const std::string& state) {state_ = state;notify("State changed to: " + state);}std::string getState() const {return state_;}
};// 具體觀察者實現
class ConcreteObserver : public IObserver, public std::enable_shared_from_this<ConcreteObserver> {
private:std::string name_;std::weak_ptr<ISubject> subject_;public:ConcreteObserver(const std::string& name, std::shared_ptr<ISubject> subject): name_(name), subject_(subject) {subject->attach(shared_from_this());}~ConcreteObserver() {if (auto subject = subject_.lock()) {subject->detach(shared_from_this());}}void update(const std::string& message) override {std::cout << "Observer " << name_ << " received: " << message << std::endl;}
};// 使用示例
int main() {auto subject = std::make_shared<ConcreteSubject>();auto observer1 = std::make_shared<ConcreteObserver>("Observer1", subject);auto observer2 = std::make_shared<ConcreteObserver>("Observer2", subject);subject->setState("Active");subject->setState("Inactive");return 0;
}