* 观察者模式
* [说明]
*  在一公文处理系统中,开发者定义了一个公文类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 CDocE

asp.net 页面事件执行顺序

xplorer
{
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;
}

posted on 2012-04-22 15:57  知识天地  阅读(1200)  评论(0编辑  收藏  举报