观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,当主题对象状态发生改变时,它会通知所有观察者对象,使它们能够自动更新自己。
下面是一个使用 C++ 实现观察者模式的示例代码:
#include <iostream>
#include <list>
#include <string>
// 抽象主题类:定义了添加、删除和通知观察者的接口
class Subject {
public:
virtual ~Subject() {}
virtual void Attach(Observer* observer) = 0;
virtual void Detach(Observer* observer) = 0;
virtual void Notify() = 0;
};
// 抽象观察者类:定义了更新的接口
class Observer {
public:
virtual ~Observer() {}
virtual void Update(Subject* subject) = 0;
};
// 具体主题类:维护观察者列表,实现添加、删除和通知观察者的接口
class ConcreteSubject : public Subject {
public:
virtual ~ConcreteSubject() {}
virtual void Attach(Observer* observer) override {
observers_.push_back(observer);
}
virtual void Detach(Observer* observer) override {
observers_.remove(observer);
}
virtual void Notify() override {
for (auto observer : observers_) {
observer->Update(this);
}
}
void SetState(const std::string& state) {
state_ = state;
}
const std::string& GetState() const {
return state_;
}
private:
std::list<Observer*> observers_;
std::string state_;
};
// 具体观察者类:实现更新的接口
class ConcreteObserver : public Observer {
public:
ConcreteObserver(const std::string& name) : name_(name) {}
virtual ~ConcreteObserver() {}
virtual void Update(Subject* subject) override {
ConcreteSubject* concrete_subject = dynamic_cast<ConcreteSubject*>(subject);
if (concrete_subject) {
std::cout << name_ << " received the update: " << concrete_subject->GetState() << std::endl;
}
}
private:
std::string name_;
};
int main() {
// 创建具体主题对象
ConcreteSubject subject;
// 创建具体观察者对象
ConcreteObserver observer1("Observer 1");
ConcreteObserver observer2("Observer 2");
ConcreteObserver observer3("Observer 3");
// 添加观察者
subject.Attach(&observer1);
subject.Attach(&observer2);
subject.Attach(&observer3);
// 修改状态并通知观察者
subject.SetState("State 1");
subject.Notify();
// 移除观察者
subject.Detach(&observer2);
// 修改状态并通知观察者
subject.SetState("State 2");
subject.Notify();
return 0;
}
在上面的代码中,我们首先定义了一个抽象主题类 Subject 和抽象观察者类 Observer,分别定义了添加、删除和通知观察者的接口和更新的接口。接着,我们创建了一个具体主题类 ConcreteSubject,它维护了一个观察者列表,并实现了添加、删除和通知观察者的接口。
同时,我们也定义了一个具体观察者类 ConcreteObserver,它实现了更新的接口。在 main() 函数中,我们创建了一个具体主题对象 subject 和三个具体观察者对象 observer1、observer2 和 observer3,并将观察者添加到主题对象中。接着,我们修改了主题对象的状态,并通知观察者。最后,我们移除了一个观察者,并再次修改主题对象的状态并通知观察者。
观察者模式的优点在于它可以将主题对象和观察者对象解耦,使得它们可以独立地变化。同时,观察者模式也提供了一种一对多的通信机制,使得系统更加灵活。但是,观察者模式可能会导致观察者对象的数量较大,从而影响系统的性能。