观察者模式类图
观察者模式的应用场景
在软件系统中,当系统一方行为依赖另一方行为的变动时,可使用观察者模式松耦合联动双方,使得一方的变动可以通知到感兴趣的另一方对象,从而让另一方对象对此做出响应。
通过前面的分析与应用实例可知观察者模式适合以下几种情形。
对象间存在一对多关系,一个对象的状态发生改变会影响其他对象。
当一个抽象模型有两个方面,其中一个方面依赖于另一方面时,可将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
实现类似广播机制的功能,不需要知道具体收听者,只需分发广播,系统中感兴趣的对象会自动接收该广播。
多层级嵌套使用,形成一种链式触发机制,使得事件具备跨域(跨越两种观察者类型)通知。
多线程安全的观察者模式
代码 来自陈硕 的linux服务端多线程编程
#include <algorithm>
#include <vector>
#include <stdio.h>
#include "../Mutex.h"
#include <boost/enable_shared_from_this.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
class Observable;
class Observer : public boost::enable_shared_from_this<Observer>
{
public:
virtual ~Observer();
virtual void update() = 0;
void observe(Observable* s);
protected:
Observable* subject_;
};
class Observable
{
public:
void register_(boost::weak_ptr<Observer> x);
// void unregister(boost::weak_ptr<Observer> x);
void notifyObservers()
{
muduo::MutexLockGuard lock(mutex_);
Iterator it = observers_.begin();
while (it != observers_.end())
{
boost::shared_ptr<Observer> obj(it->lock());
if (obj)
{
obj->update();
++it;
}
else
{
printf("notifyObservers() erase\n");
it = observers_.erase(it);
}
}
}
private:
mutable muduo::MutexLock mutex_;
std::vector<boost::weak_ptr<Observer> > observers_;
typedef std::vector<boost::weak_ptr<Observer> >::iterator Iterator;
};
Observer::~Observer()
{
// subject_->unregister(this);
}
void Observer::observe(Observable* s)
{
s->register_(shared_from_this());
subject_ = s;
}
void Observable::register_(boost::weak_ptr<Observer> x)
{
observers_.push_back(x);
}
//void Observable::unregister(boost::weak_ptr<Observer> x)
//{
// Iterator it = std::find(observers_.begin(), observers_.end(), x);
// observers_.erase(it);
//}
// ---------------------
class Foo : public Observer
{
virtual void update()
{
printf("Foo::update() %p\n", this);
}
};
int main()
{
Observable subject;
{
boost::shared_ptr<Foo> p(new Foo);
p->observe(&subject);
subject.notifyObservers();
}
subject.notifyObservers();
}