作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处
观察者模式
观察者模式(Observer Pattern)用于对象间存在一对多关系。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
使用场景
- 当一个对象的数据更新时需要通知其他对象,但这个对象又不希望和被通知的那些对象形成紧耦合。
- 当一个对象的数据更新时,这个对象需要让其他对象也各自更新自己的数据,但这个对象不知道具体有多少对象需要更新数据。
优缺点
-
优点:
1、观察者和被观察者是抽象耦合的。
2、建立一套触发机制。 -
缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
注意事项
1、避免循环引用。
2、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
UML结构图
代码实现
interface.h
创建抽象类 - 观察者;创建子类 - 3个观察者
#include <iostream>
using namespace std;
class Observer //基类-观察者
{
public:
Observer() {}
virtual ~Observer() {}
virtual void update() = 0;
};
class BinaryObserver: public Observer //子类-观察者1
{
public:
void update() { cout << "BinaryObserver update" << endl; }
};
class OctalObserver: public Observer //子类-观察者2
{
public:
void update() { cout << "OctalObserver update" << endl; }
};
class HexaObserver: public Observer //子类-观察者3
{
public:
void update() { cout << "HexaObserver update" << endl; }
};
subject.h
创建主题类,存在一种状态可以被外界改变,并且可以包含所有的观察者
#include <vector>
#include "interface.h"
class Subject
{
public:
Subject(size_t state) : state(state) {}
size_t getState() { return this->state; }
void setState(size_t state) {
this->state = state;
notifyAllObservers(); //状态改变提醒所有观察者
}
void attach(Observer *observer)
{
vector.push_back(observer);
}
void notifyAllObservers()
{
for(auto itor : vector)
{
itor->update();
}
}
private:
std::vector<Observer *> vector;
size_t state;
};
main.cpp
实例应用 - 在主题中添加观察者,当状态改变时通知所有观察者执行对应的操作
#include "subject.h"
int main()
{
Subject *subject = new Subject(10);
Observer *binaryObserver = new BinaryObserver();
Observer *octalObserver = new OctalObserver();
Observer *hexaObserver = new HexaObserver();
//添加观察者
subject->attach(binaryObserver);
subject->attach(octalObserver);
subject->attach(hexaObserver);
cout << subject->getState() << endl;
subject->setState(20);
cout << subject->getState() << endl;
return 0;
}
运行结果:
10
BinaryObserver update
OctalObserver update
HexaObserver update
20