本文共 2393 字,大约阅读时间需要 7 分钟。
在一公文处理系统中,开发者定义了一个公文类OfficeDoc, 其中定义了公文具有的属性和处理公文的相应方法。当公文件的内容或
*状态发生变化时,关注此OfficeDoc 类对象的相应的DocExplorer 对象都要更新其自身的状态。一个OfficeDoc 对象能够关联一组 *DocExplorer 对象。当OfficeDoc 对象的内容或状态发生变化时,所有与之相关联的DocExplorer对象都将得到通知,这种应用被称 *为观察者模式。 * * 例如MFC的DOC、VIEW架构都是基于这种观察者的模式。 * 本代码还用了一种标示的方法实现了在运行时辨识对象。 * RTTI只能在运行时实现类型的识别。没法实现对象的识别。#include <stdio.h>
#include <typeinfo>// 最多与OfficeDoc关联的DocExplorer对象的个数
const int OBS_MAX = 20;class COfficeDoc;
// 关注OfficeDoc公文对象的类
//##ModelId=44D02B1A01B9 class CDocExplorer { public: //##ModelId=44D02B1A01BA CDocExplorer(COfficeDoc *doc); //##ModelId=44D02B1A01BC void UpdateSelf(COfficeDoc *doc);
// 为了实现对象的识别,在此加一个标示
//##ModelId=44D02B1A01BE int nExplorerID; };//##ModelId=44D02B1A01D4
class COfficeDoc { public: //##ModelId=44D02B1A01D5 COfficeDoc() { index = 0; } //##ModelId=44D02B1A01D6 void Attach(CDocExplorer *e) { if(index >= OBS_MAX || e == NULL) { return; } myObs[index] = e; index++;e->nExplorerID = index;
}//##ModelId=44D02B1A01E4
void Detach(CDocExplorer *e) { for(int i = 0; i <index; i++) { if(myObs[i] == e) { // 把当前位置的观察者对象和最后一个对象交换,并把indexhttp://www.sensiblefinds.com的值减一个 if(i <= index-2) myObs[i] = myObs[index-1]; myObs[index - 1] = NULL; index--; break; } } } // 修改数据,并通知观察者更新 //##ModelId=44D02B1A01E6 void ModifyData(int data) { printf("公文的数据改变成:%d/n", data); m_nData = data; NotifyObs(); }private:
//##ModelId=44D02B1A01E9 CDocExplorer *myObs[OBS_MAX];// 观察者的类对象指针数组 //##ModelId=44D02B1A01F4 int index;// 通知所有的观察者对象改变自己的状态
//##ModelId=44D02B1A01F5 void NotifyObs() { for(int i = 0; i < index; i++) { myObs[i]->UpdateSelf(this); } } public: // 公文的数据 //##ModelId=44D02B1A01F6 int m_nData; }; //##ModelId=44D02B1A01BA CDocExplorer::CDocExplorer(COfficeDoc *doc) { doc->Attach(this); }//##ModelId=44D02B1A01BC
void CDocExplorer::UpdateSelf(COfficeDoc *doc) { // 把下面两行的注释打开还可以看到typeid和type_info的用法 // 会发现typeid只能实现类型的识别//const type_info &t = typeid(*doc);
//printf("我正在观察%s/n"http://www.pm300.com/, t.name()); printf("我是观察者%d, ", nExplorerID); printf("更新数据: %d /n", doc->m_nData); }int main()
{ COfficeDoc officeDoc; CDocExplorer docExplorer0(&officeDoc); CDocExplorer docExplorer1(&officeDoc); CDocExplorer docExplorer2(&officeDoc); CDocExplorer docExplorer3(&officeDoc); CDocExplorer docExplorer4(&officeDoc); // 更新公文的数据 officeDoc.ModifyData(123); printf("/n"); officeDoc.ModifyData(567); return 0; }本文转自博客园知识天地的博客,原文链接:,如需转载请自行联系原博主。