1. 介绍
观察者模式:定义了一种“一对多”的依赖关系,让多个观察者对象同时监听一个对象的改变,即当该对象的状态发现改变时,会通知所有它依赖的观察者对象。观察者模式属于行为模式。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
主要解决:通知其他对象有一个对象的状态改变,而且同时要考虑到易用和低耦合,保证高度的协作。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
直白点,观察者模式就是构建“事件”来通知某种状态的改变。
观察者模式提供了一种对象设计,让主题和观察者之间松耦合:
- 运行时我们用新的观察者取代现有的观察者,主题不会受到影响;
- 有新类型的观察者出现时,主题代码不需要更改;
- 可以轻易地独立使用或复用主题或者观察者;
- 改变主题或者观察者的任何一方都不会影响另一方。
2. UML
简单的UML图可以表示如下:
观察者模式定义了四种角色:抽象主题、具体主题、抽象观察者、具体观察者。
抽象主题(Subject):该角色是一个抽象类或接口,定义了增加、删除、通知观察者对象的方法。
具体主题(ConcreteSubject):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
抽象观察者(Observer):该角色是具体观察者的抽象类,定义了一个更新方法。
具体观察者(ConcrereObserver):该角色是具体的观察者对象,在得到具体主题更改通知时更新自身的状态。
C++中具体存在的类各你的代码设计有关,可能某个类同时承担抽象主题和具体主题,或者抽象观察者和具体观察者的角色。
3. 具体实例
首先观察者类:
class Observer
{ public: virtual void OnUpdata() = 0;
};class AObserver : public Observer
{ public: virtual void OnUpdata() {std::cout << "-------OnUpdata----A----";}
};class BObserver : public Observer
{ public: virtual void OnUpdata() {std::cout << "-------OnUpdata----B----";}
};
然后主题类:
class SubjectBase{
public: virtual void AddObserver(std::shared_ptr<Observer> observer) = 0; virtual void RemoveObserver(std::shared_ptr<Observer> observer) = 0; virtual void NotifyUpdate() = 0;
};class SubjectTest : public SubjectBase {
public: void AddObserver(std::shared_ptr<Observer> observer) override {observers_.push_back(observer);} void RemoveObserver(std::shared_ptr<Observer> observer) override {observers_.remove(observer)}void NotifyUpdate() override {for(auto observer : observers_)observers_->OnUpdata();}
private:std::list<std::shared_ptr<Observer> > observers_;
};
Chromium代码中有大量使用观察者模式,比如网络的连接、应用的启动和关闭等等。