一、定义
观察者(Observer)模式 定义如下:
是一种对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
二、观察者模式组成:
- 抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。
- 抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。在本角色内也可以维护一个指向抽象目标角色的指针,通过这个指针在抽象观察者角色的构造函数调用抽象目标角色的注册函数,在析构函数调用抽象目标角色的删除;
- 具体目标角色(Concrete Subject):当它的状态发生改变时, 向它的各个观察者发出通知。
- 具体观察者角色(Concrete Observer):实现Observer 的更新接口以使自身状态与目标的状态保持一致。
三、 总结
1.观察者模式 主要解决了什么问题?
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。
2.观察者模式 何时使用?
一个对象的状态发生改变,所有的依赖对象都将得到通知,进行广播通知。
3、观察者模式 的优缺点
【优点】
- 观察者和被观察者是抽象耦合的。
- 建立一套触发机制。
【缺点】
- 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
- 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
- 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
四、 代码示例:
#include <iostream>
#include <vector>
#include <algorithm>
// 抽象观察者角色
class Subject;
class Observer {
public:
virtual ~Observer() {
if (subject) {
subject->detach(this);
}
}
virtual void update() = 0;
protected:
Observer(Subject* sub) : subject(sub) {
subject->attach(this);
}
Subject* subject;
};
// 抽象目标角色
class Subject {
public:
virtual ~Subject() {}
void attach(Observer* observer) {
observers.push_back(observer);
}
void detach(Observer* observer) {
observers.erase(std::remove(observers.begin(), observers.end(), observer), observers.end());
}
void notify() {
for (Observer* observer : observers) {
observer->update();
}
}
private:
std::vector<Observer*> observers;
};
// 具体目标角色
class ConcreteSubject : public Subject {
public:
void setState(int state) {
this->state = state;
notify();
}
int getState() const {
return state;
}
private:
int state;
};
// 具体观察者角色
class ConcreteObserver : public Observer {
public:
ConcreteObserver(ConcreteSubject* sub) : Observer(sub), subject(sub) {}
void update() override {
std::cout << "Observer: Subject's state is " << subject->getState() << std::endl;
}
private:
ConcreteSubject* subject;
};
int main() {
ConcreteSubject subject;
ConcreteObserver observer1(&subject);
ConcreteObserver observer2(&subject);
subject.setState(1);
subject.setState(2);
return 0;
}