Observer 模式应该可以说是应用最多、影响最广的模式之一,因为 Observer 的一个实例 Model/View/Control(MVC) 结构在系统开发架构设计中有着很重要的地位和意义, MVC实现了业务逻辑和表示层的解耦。 个人也认为 Observer 模式是软件开发过程中必须要掌握和使用的模式之一。在 MFC 中, Doc/View(文档视图结构)提供了实现 MVC 的框架结构(有一个从设计模式(Observer 模式)的角度分析分析 Doc/View 的文章正在进一步的撰写当中,遗憾的是时间:))。在 Java 阵容中, Struts 则提供和 MFC 中 Doc/View 结构类似的实 现 MVC 的框架。另外 Java 语言本身就提供了 Observer 模式的实现接口,这将在讨论中给出。当然, MVC 只是 Observer 模式的一个实例。 Observer 模式要解决的问题为: 建立一个一(Subject)对多(Observer) 的依赖关系, 并且做到当“一” 变化的时候, 依赖这个“一”的多也能够同步改变。 最常见的一个例子就是: 对同一组数据进行统计分析时候, 我们希望能够提供多种形式的表示(例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据, 我们当然需要当数据改变的时候, 所有的统计的显示都能够
同时改变。 Observer 模式就是解决了这一个问题。
这里的目标 Subject 提供依赖于它的观察者 Observer 的注册(Attach) 和注销(Detach)操作,并且提供了使得依赖于它的所有观察者同步的操作(Notify)。 观察者 Observer 则提供一个 Update 操作, 注意这里的 Observer 的 Update 操作并不在 Observer 改变了 Subject 目标状态的时候就对自己进行更新, 这个更新操作要延迟到 Subject 对象发出 Notify 通知所有
Observer 进行修改(调用 Update)。
实现:
代码示例:
#include <iostream> #include <map> #include <vector> #include <string> using namespace std; /* 1.监听者 处理事件 2.观察者 观察事件 并通知监听者处理 保存 事件 及 对事件感兴趣的监听者标识 map<int,vector> */ class Listener { public: Listener(string name) :mname(name){} virtual void handleListenerMessage(int imessage)const = 0; protected: string mname; }; class TestListener : public Listener { public: TestListener(string name) :Listener(name){} // virtual void handleListenerMessage(int imessage)const { cout << "Listener:" << mname << " "; switch (imessage) { case 1: cout << "1 recv!" << endl; break; case 2: cout << "2 recv!" << endl; break; case 3: cout << "3 recv!" << endl; default: cout << "no handle!" << endl; break; } } }; /* Listener1 1,3 Listener2 2,3 Listener3 1,2 */ class Observe { public: /* 1.事件已经被注册 Listener 插入到集合 2.事件未被注册 Listener和message插入到映射 */ void registerMessage(const Listener* plistener, int imessage) { map<int, vector<const Listener*>>::iterator rit = mymap.find(imessage); if (rit == mymap.end()) { vector<const Listener*> vec; vec.push_back(plistener); mymap[imessage] = vec; } else { rit->second.push_back(plistener); } } /* 1.注册 通知对于该事件感兴趣的监听者处理 2.未注册 */ void handleMessage(int imessage) { map<int, vector<const Listener*>>::iterator rit = mymap.find(imessage); if (rit == mymap.end()) { cout << "no listener interest!" << endl; return; } vector<const Listener*>::iterator it = rit->second.begin(); for (it; it != rit->second.end(); ++it) { (*it)->handleListenerMessage(imessage); } } private: map<int, vector<const Listener *>> mymap; }; int main() { Listener* p1 = new TestListener("Listener1"); Listener* p2 = new TestListener("Listener2"); Listener* p3 = new TestListener("Listener3"); Observe ob; ob.registerMessage(p1, 1); ob.registerMessage(p1, 3); ob.registerMessage(p2, 2); ob.registerMessage(p2, 3); ob.registerMessage(p3, 1); ob.registerMessage(p3, 2); ob.handleMessage(2); return 0; }
运行结果: