观察者模式包含两个对象,一个是观察者,一个是被观察者。一般而言,观察者可以有多个,被观察者只有1个。当被观察者有任何的状态变化时,会通知到所有的观察者,观察者根据状态的不同做出不同的行为。
在 GoF 4 人编写的《设计模式》中对观察者模式给出下面一个例子:
例如在 Excel 中,当数据发生变化时,柱状图、饼状图等等对象都会发生变化。即:被观察者为数据,而观察者为柱状图、饼状图这些对象。
从这个例子,我们可以理解到,当我们面向对象编码时,当一个对象的变化需要其他的对象同时改变时,使用观察者模型进行编码,代码逻辑将会变得很清晰。
#include <iostream>
#include <set>
using namespace std;
class Observer
{
public:
virtual void update() = 0;
};
class Subject
{
public:
// 注册观察者
void attach(Observer *observer)
{
m_observers.insert(observer);
}
// 移除观察者
void detach(Observer *observer)
{
m_observers.erase(observer);
}
// 通知函数
void notify()
{
cout << "被观察者状态发生变化..." << endl;
for(Observer * observer : m_observers)
{
observer->update();
}
}
~Subject()
{
for (Observer* observer : m_observers)
{
delete observer;
}
}
private:
set<Observer*> m_observers;
};
// 定义具体观察者
class Observer1 : public Observer
{
public:
void update()
{
cout << "Observer1 更新行为" << endl;
}
void play()
{
cout << "Observer1 其他行为" << endl;
}
};
class Observer2 : public Observer
{
public:
void update()
{
cout << "Observer2 更新行为" << endl;
}
void speak()
{
cout << "Observer2 其他行为" << endl;
}
};
void test()
{
// 实例化观察者
Observer* ob1 = new Observer1;
Observer* ob2 = new Observer2;
// 实例化被观察者
Subject subject;
subject.attach(ob1);
subject.attach(ob2);
// 假设:被观察者状态发生变化,开始通知观察者
// 观察者做出相应的动作行为
subject.notify();
}
int main()
{
test();
return 0;
}
上述示例代码中,我们只对观察者进行了抽象。当然也可以对被观察者进行抽象。另外,当被观察者状态发生变化时,也可以通过 update 函数将状态码通知给具体的观察者,观察者根据具体的状态来做出更加复杂的行为。

冀公网安备13050302001966号