观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当该主题对象发生变化时,会通知所有观察者对象,使它们能够自动更新。
组成部分
- Subject(主题):主题对象保存了一系列观察者对象,并提供注册、注销和通知方法。
- Observer(观察者):定义了一个更新接口,以便主题对象在其状态变化时通知它们。
- ConcreteSubject(具体主题):具体主题对象在其内部状态发生变化时通知所有注册的观察者。
- ConcreteObserver(具体观察者):具体观察者实现更新接口,以便使自身状态与主题的状态保持一致。
C++示例
以下是一个使用观察者模式的C++示例,展示了如何定义和使用观察者模式:
#include <iostream>
#include <vector>
#include <memory>
#include <algorithm>
// 观察者接口
class Observer {
public:
virtual void update(class Subject* subject) = 0;
virtual ~Observer() = default;
};
// 主题类
class Subject {
public:
virtual void attach(Observer* observer) = 0;
virtual void detach(Observer* observer) = 0;
virtual void notify() = 0;
virtual int getState() const = 0;
virtual void setState(int newState) = 0;
virtual ~Subject() = default;
};
// 具体主题类
class ConcreteSubject : public Subject {
private:
int state;
std::vector<Observer*> observers;
public:
void attach(Observer* observer) override {
observers.push_back(observer);
}
void detach(Observer* observer) override {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() override {
for (Observer* observer : observers) {
observer->update(this);
}
}
int getState() const override {
return state;
}
void setState(int newState) override {
state = newState;
}
};
// 具体观察者类
class ConcreteObserver : public Observer {
private:
int observerState;
Subject* subject;
public:
//具体观察者一般都是有Subject对象的
ConcreteObserver(Subject* subj) : subject(subj) {}
void update(Subject* subject) override {
if (this->subject == subject) {
observerState = subject->getState();
std::cout << "Observer State Updated: " << observerState << std::endl;
}
}
};
class ConcreteObserver2 : public Observer {
private:
int observerState;
Subject* subject;
public:
//具体观察者一般都是有Subject对象的
ConcreteObserver2(Subject* subj) : subject(subj) {}
void update(Subject* subject) override {
if (this->subject == subject) {
observerState = subject->getState();
std::cout << "Observer2 State Updated: " << observerState << std::endl;
}
}
};
int main() {
Subject* subject = new ConcreteSubject();
Observer* observer1 = new ConcreteObserver(subject);
Observer* observer2 = new ConcreteObserver2(subject);
subject->attach(observer1);
subject->attach(observer2);
subject->setState(10);
subject->notify();
subject->setState(20);
subject->notify();
subject->detach(observer1);
subject->setState(30);
subject->notify();
delete observer1;
delete observer2;
delete subject;
return 0;
}
代码解释
- Observer:定义了一个纯虚函数
update
,表示观察者接口。 - ConcreteObserver:实现了
Observer
接口,在update
方法中更新自身状态。 - Subject:维护一个观察者列表,提供
attach
、detach
和notify
方法。 - ConcreteSubject:继承
Subject
,并在状态改变时通知所有观察者。
优点
- 松耦合:主题和观察者之间的耦合度很低,它们可以独立变化。
- 易扩展:可以根据需要增加或删除观察者,而无需修改主题类。
缺点
- 通知顺序不确定:观察者接收到通知的顺序是不确定的。
- 可能引起性能问题:如果观察者很多,通知所有观察者可能会花费较多时间。
通过使用观察者模式,可以使得对象之间的依赖关系更加灵活和松散,便于维护和扩展。