博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++观察者模式
阅读量:6615 次
发布时间:2019-06-24

本文共 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 CDocE

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

本文转自博客园知识天地的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
如何检测域名是否被微信屏蔽 微信域名检测接口API是如何实现
查看>>
POJ1611-The Suspects
查看>>
Linux下安装Python-3.3.2【转】
查看>>
LeetCode OJ:Merge Two Sorted Lists(合并两个链表)
查看>>
功能测试
查看>>
【BZOJ 1901】Dynamic Rankings
查看>>
【转】聚集索引和非聚集索引的区别
查看>>
Github-Client(ANDROID)开源之旅(二) ------ 浅析ActionBarSherkLock
查看>>
eclipse中如何去除警告:Class is a raw type. References to generic type Class<T> should be parameterized...
查看>>
React-Native 之 GD (十六)首页筛选功能
查看>>
SSISDB5:使用TSQL脚本执行Package
查看>>
asp.net后台进程做定时任务
查看>>
给vs2012换肤
查看>>
java接口中多继承的问题
查看>>
索引笔记《二》确定需要建立索引的列
查看>>
libjpeg的问题
查看>>
Ubuntu+Apache+PHP+Mysql环境搭建(完整版)
查看>>
深度学习笔记之CNN(卷积神经网络)基础
查看>>
ORACLE expdp备份与ORA-31693、ORA-02354、ORA-02149
查看>>
嵌入式 详解udev
查看>>