观察者模式

来源:互联网 发布:98362什么意思网络语 编辑:程序博客网 时间:2024/06/06 06:37

这几天由于一直在研究智能指针,由weak_ptr解决shared_ptr的循环引用问题得到了weak_ptr是shared_ptr的观察者模式(又称发布-订阅模式)的理论。但是观察者模式是怎么回事呢。先引用一段设计模式的原文:

Intent :
Define a one-to-many dependency between objects so that when oneobject changes state, all its dependents are notified and updated automatically.

即在被观察者和观察者之间定义一个一对多的依赖关系,当被观察者状态改变时,观察者就会被通知并且更新其状态。

Applicability:

应用:

When an abstraction has two aspects, one dependent on the other.Encapsulating these aspects in separate objects lets you vary and reuse them independently.
情况一:有两个事件,一个依赖于另一个,可以分别封装这两个事件以提高变化性和重用性。
When a change to one object requires changing others, and you don't know how many objects need to be changed.
情况二:当一个对象的改变会引起其他的对象的改变,而你又不知道会影响多少个的时候。
When an object should be able to notify other objects without making assumptions about who these objects are. In other words, you don't want these objects tightly coupled.
情况三:当一个对象需要通知其他对象而又不想知道他们是谁的时候。换句话说就是不想让这些对象耦合太紧的时候。(个人感觉是跟第二个说的一回事)

下面是官方的UML图:

很常见的例子为天气预报订阅,手机可以订阅某些城市的天气情况,那么手机就是这些地区天气情况的观察者,当天气发生改变时通知到手机,手机再更新本地的天气情况的信息。

下图是我仿写的一个简单的例子来说明。首先给出UML图


#ifndef OBSERVER_H#define OBSERVER_H#include <iostream>#include <boost/shared_ptr.hpp>#include <list>using namespace std;using namespace boost;class IObserver//Observer接口类{public:virtual void UpdateInfo(int id)=0;};class ISubject//被观察者Target接口类{public:virtual void Register(shared_ptr<IObserver> observer)=0;virtual void ObserverRemove(shared_ptr<IObserver> observer)=0;virtual void Notify()=0;};#endif
#include "Observer.h"using namespace std;using namespace boost;class A : public IObserver{public:A(int id):tid(id){}void UpdateInfo(int id);private:int tid;};void A::UpdateInfo(int id){cout << id << endl;}class D:public ISubject{public:D(int str):id(str){};void Register(shared_ptr<IObserver> observer);void ObserverRemove(shared_ptr<IObserver> observer);void Notify();private:list<shared_ptr<IObserver>> ListofObserver;//每个被观察者都有一个存贮观察者的指针的容器。以方便对多个观察者进行通知int id;};void D::Register(shared_ptr<IObserver> observer)//注册函数,用于存贮观察者的指针{ListofObserver.push_back(observer);}void D::ObserverRemove(shared_ptr<IObserver> observer)//移除函数,用于移除观察者,也就是说被观察者有权解除观察者的观察{ListofObserver.remove(observer);}void D::Notify()//通知观察者,这里一般都是调用观察者提供的方法,或者返回给观察者一个状态{for(list<shared_ptr<IObserver>>::iterator it = ListofObserver.begin();it != ListofObserver.end();++it){(*it)->UpdateInfo(id);}}int main(int,char**){shared_ptr<IObserver> p1(new A(1));//shared_ptr<IObserver> p2(new A(2));//构建两个观察者shared_ptr<ISubject> p3(new D(3));//shared_ptr<ISubject> p4(new D(4));//构建两个被观察者p3->Register(p1);p4->Register(p2);//分别注册p3->Notify();p4->Notify();//分别通知}
上面的代码只是表达了两个观察者分别订阅两个被观察者的例子,之所以这个模式被称为订阅-发布模式也是这个道理,由于多态性,发布者不需要知道究竟谁订阅过,只需要在状态改变的时候发布即可,若干订阅者自会收到状态改变的通知的。


原创粉丝点击