C++ 观察者模式样例
C++ 观察者模式样例
#include <iostream>
#include <set>
#include <string>
using namespace std;
/////////////////////抽象模式定义
class CObservable;
//观察者,纯虚基类
class CObserver
{
public:
CObserver::CObserver(){};
virtual CObserver::~CObserver(){};
//当被观察的目标发生变化时,通知调用该方法
//来自被观察者pObs, 扩展參数为pArg
virtual void Update(CObservable* pObs, void* pArg = NULL) = 0;
};
//被观察者,即Subject
class CObservable
{
public:
CObservable() : m_bChanged(false) {};
virtual ~CObservable() {};
//注冊观察者
void Attach(CObserver* pObs);
//注销观察者
void Detach(CObserver* pObs);
//注销全部观察者
void DetachAll();
//若状态变化,则遍历观察者,逐个通知更新
void Notify(void* pArg = NULL);
//測试目标状态是否变化
bool HasChanged();
//获取观察者数量
int GetObserversCount();
protected:
//设置状态变化!!!必须继承CObservable才干设置目标状态
void SetChanged();
//初始化目标为未变化状态
void ClearChanged();
private:
bool m_bChanged; //状态
set<CObserver*> m_setObs; //set保证目标唯一性
};
/////////////////////抽象模式实现
void CObservable::Attach(CObserver* pObs)
{
if (!pObs) return;
m_setObs.insert(pObs);
}
void CObservable::Detach(CObserver* pObs)
{
if (!pObs) return;
m_setObs.erase(pObs);
}
void CObservable::DetachAll()
{
m_setObs.clear();
}
void CObservable::SetChanged()
{
m_bChanged = true;
}
void CObservable::ClearChanged()
{
m_bChanged = false;
}
bool CObservable::HasChanged()
{
return m_bChanged;
}
int CObservable::GetObserversCount()
{
return m_setObs.size();
}
void CObservable::Notify(void* pArg /* = NULL */)
{
if (!HasChanged()) return;
cout << "notify observers…" << endl;
ClearChanged();
set<CObserver*>::iterator itr = m_setObs.begin();
for (; itr != m_setObs.end(); itr++)
{
(*itr)->Update(this, pArg);
}
}
/////////////////////详细应用类定义和实现
//bloger是公布者,即被观察者(subject)
class CBloger : public CObservable
{
public:
void Publish(const string &strContent)
{
cout << "bloger publish, content: " << strContent << endl;
SetChanged();
Notify(const_cast<char*>(strContent.c_str()));
}
};
//portal是公布者,即被观察者(subject)
class CPortal : public CObservable
{
public:
void Publish(const string &strContent)
{
cout << "portal publish, content: " << strContent << endl;
SetChanged();
Notify(const_cast<char*>(strContent.c_str()));
}
};
//RSS阅读器,观察者
class CRSSReader : public CObserver
{
public:
CRSSReader(const string &strName) : m_strName(strName){}
virtual void Update(CObservable* pObs, void* pArg = NULL)
{
char* pContent = static_cast<char*>(pArg);
//观察多个目标
if (dynamic_cast<CBloger*>(pObs))
{
cout << m_strName << " updated from bloger, content: " << pContent << endl;
}
else if (dynamic_cast<CPortal*>(pObs))
{
cout << m_strName << " updated from portal, content: " << pContent << endl;
}
}
private:
string m_strName;
};
//Mail阅读器,观察者
class CMailReader : public CObserver
{
public:
CMailReader(const string &strName) : m_strName(strName){}
virtual void Update(CObservable* pObs, void* pArg = NULL)
{
char* pContent = static_cast<char*>(pArg);
if (dynamic_cast<CBloger*>(pObs))
{
cout << m_strName << " updated from bloger, content: " << pContent << endl;
}
if (dynamic_cast<CPortal*>(pObs))
{
cout << m_strName << " updated from portal, content: " << pContent << endl;
}
}
private:
string m_strName;
};
/////////////////Main
int main()
{
//目标(被观察者)
CBloger* pBloger = new CBloger();
CPortal* pPortal = new CPortal();
//观察者. 一个观察者能够观察多个目标
CRSSReader* pRssReader = new CRSSReader("rss reader");
CMailReader* pMailReader = new CMailReader("mail reader");
pBloger->Attach(pRssReader); //bloger注冊观察者
pBloger->Attach(pMailReader); //bloger注冊观察者
pPortal->Attach(pRssReader); //portal注冊观察者
pPortal->Attach(pMailReader); //portal注冊观察者
//博客公布信息
pBloger->Publish("博客分享设计模式");
cout << endl;
//门户公布信息
pPortal->Publish("门户分享设计模式");
cout << "\nportal detached mail reader" << endl;
pPortal->Detach(pMailReader);
cout << "portal observers count: " << pPortal->GetObserversCount() << endl << endl;
pPortal->Publish("门户分享设计模式");
system("pause");
return 0;
}
C++ 观察者模式样例的更多相关文章
- java设计模式演示样例
创建模式 1.工厂方法模式(Factory Method) 将程序中创建对象的操作,单独出来处理,创建一个产品的工厂接口,把实际的工作转移到详细的子类.大大提高了系统扩展的柔性,接口的抽象化处理给相 ...
- C++的性能C#的产能?! - .Net Native 系列《三》:.NET Native部署测试方案及样例
之前一文<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥> 获得很多朋友支持和鼓励,也更让我坚定做这项技术的推广者,希望能让更多的朋友了解这项技术,于是先从官方 ...
- MarkDown+LaTex 数学内容编辑样例收集
$\color{green}{MarkDown+LaTex 数学内容编辑样例收集}$ 1.大小标题的居中,大小,颜色 [例1] $\color{Blue}{一元二次方程根的分布}$ $\color{R ...
- 33个超级有用必须要收藏的PHP代码样例
作为一个正常的程序员,会好几种语言是十分正常的,相信大部分程序员也都会编写几句PHP程序,如果是WEB程序员,PHP一定是必备的,即使你没用开发过大型软件项目,也一定多少了解它的语法. 在PHP的流行 ...
- 关于peersim样例配置文件的超详细解读(新手勿喷)
相信很多兄弟一开始接触peersim,对配置文件还是有点不适应,我看了好久的样例的配置文件,一层层去找对应的文件的方法,终于好像悟懂了一点,记下来以后回顾. 贴上代码,一点点分析. 首先要说下所谓的配 ...
- hdu 1003 MAX SUM 简单的dp,测试样例之间输出空行
测试样例之间输出空行,if(t>0) cout<<endl; 这样出最后一组测试样例之外,其它么每组测试样例之后都会输出一个空行. dp[i]表示以a[i]结尾的最大值,则:dp[i ...
- CloudSim样例分析
自带八个样例描述: cloudsim-2.1.1\examples目录下提供了一些CloudSim样例程序,每个样例模拟的环境如下: (1)CloudSimExample1.Java:创建一个一台主机 ...
- 样例20-汽车SHOW
观看样例点这里 素材下载 1.设置场景大小为400*3002.执行:文件->导入->导入到库,选择需要的汽车图片文件,将其导入到库面板中3.按照同样的方式,在库面板中导入所需的背景音乐文件 ...
- java使用xsd校验xml样例
知识点:XSD文件是指XML结构定义 ( XML Schemas Definition )文件,是DTD的替代品.可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其 ...
随机推荐
- iOS UIWebView 之 UIProgressView
之前做等待跳转都是用UIActivityIndicatorView ,后来做webView 加载页面的时候,发现了一个特别好用又超级炫酷的加载提示NJKWebViewProgress,作者巧妙的通过计 ...
- android 根据域名得到IP
public static String GetInetAddress(String host) { String IPAddress = ""; InetAddress Retu ...
- 字符串如何判断null.
转http://blog.sina.com.cn/s/blog_48cd37140101awgq.html Java中判断String不为空的问题 一.判断一个字符串str不为空的方法有: 1. st ...
- UVA 10020 Minimal coverage(贪心 + 区间覆盖问题)
Minimal coverage The Problem Given several segments of line (int the X axis) with coordinates [Li, ...
- scanf()常犯错误
------------------------------------------------------------------------ <> 本意:接收字符串. 写成代码:voi ...
- JRE 和 JDK 的区别是什么?
JRE: Java Runtime Environment JDK:Java Development Kit JRE顾名思义是java运行时环境,包含了java虚拟机,java基础类库.是使用java ...
- Java 多线程-生产者、消费者
一.整体代码 ThreadDemo.java public class ThreadDemo { public static void main(String[] args) { Godown god ...
- JAVA之等号、传类对象参数与c++的区别
在JAVA中用等号对类对象进行赋值,实际上操作的是对象的地址. eg: package MyText; class ClassA { int value; public void seta(int v ...
- APEC计划指引我们前进:云计算服务将上升
APEC纲领指引我们前进:云计算服务业必将兴起 这是APEC领导人的合影: 这次APEC会议通过了<北京纲领>和<亚太伙伴关系声明>,进一步明白了亚太地区经济合作的发展方向.目 ...
- UVA 10815 Andy's First Dictionary(字符处理)
Andy, 8, has a dream - he wants to produce his very own dictionary. This is not an easy task for him ...