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++ 观察者模式样例的更多相关文章

  1. java设计模式演示样例

    创建模式 1.工厂方法模式(Factory Method)  将程序中创建对象的操作,单独出来处理,创建一个产品的工厂接口,把实际的工作转移到详细的子类.大大提高了系统扩展的柔性,接口的抽象化处理给相 ...

  2. C++的性能C#的产能?! - .Net Native 系列《三》:.NET Native部署测试方案及样例

    之前一文<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥> 获得很多朋友支持和鼓励,也更让我坚定做这项技术的推广者,希望能让更多的朋友了解这项技术,于是先从官方 ...

  3. MarkDown+LaTex 数学内容编辑样例收集

    $\color{green}{MarkDown+LaTex 数学内容编辑样例收集}$ 1.大小标题的居中,大小,颜色 [例1] $\color{Blue}{一元二次方程根的分布}$ $\color{R ...

  4. 33个超级有用必须要收藏的PHP代码样例

    作为一个正常的程序员,会好几种语言是十分正常的,相信大部分程序员也都会编写几句PHP程序,如果是WEB程序员,PHP一定是必备的,即使你没用开发过大型软件项目,也一定多少了解它的语法. 在PHP的流行 ...

  5. 关于peersim样例配置文件的超详细解读(新手勿喷)

    相信很多兄弟一开始接触peersim,对配置文件还是有点不适应,我看了好久的样例的配置文件,一层层去找对应的文件的方法,终于好像悟懂了一点,记下来以后回顾. 贴上代码,一点点分析. 首先要说下所谓的配 ...

  6. hdu 1003 MAX SUM 简单的dp,测试样例之间输出空行

    测试样例之间输出空行,if(t>0) cout<<endl; 这样出最后一组测试样例之外,其它么每组测试样例之后都会输出一个空行. dp[i]表示以a[i]结尾的最大值,则:dp[i ...

  7. CloudSim样例分析

    自带八个样例描述: cloudsim-2.1.1\examples目录下提供了一些CloudSim样例程序,每个样例模拟的环境如下: (1)CloudSimExample1.Java:创建一个一台主机 ...

  8. 样例20-汽车SHOW

    观看样例点这里 素材下载 1.设置场景大小为400*3002.执行:文件->导入->导入到库,选择需要的汽车图片文件,将其导入到库面板中3.按照同样的方式,在库面板中导入所需的背景音乐文件 ...

  9. java使用xsd校验xml样例

    知识点:XSD文件是指XML结构定义 ( XML Schemas Definition )文件,是DTD的替代品.可以用一个指定的XML Schema来验证某个XML文档,以检查该XML文档是否符合其 ...

随机推荐

  1. 直播时代--IOS直播客户端SDK,美艳直播【开源】

    看到该文章我非常喜欢,为了方便自己查看和参考所以将其复制过来,源文地址:http://www.cnblogs.com/runner42/p/5241407.html 请支持原作者.原作者如看到请原谅复 ...

  2. K - K.Bro Sorting

    Description Matt’s friend K.Bro is an ACMer. Yesterday, K.Bro learnt an algorithm: Bubble sort. Bubb ...

  3. javascript面向对象——继承

    javascript和其他语言相比,它没有真正意义上的继承,也不能从一个父类extends,要实现它的继承可以通过其他方式来实现: 步骤:1.继承父类的属性 2.继承父类的原型 下面就以一个拖拽为例子 ...

  4. ubuntu12.04中如何设定中文输入法

    安装 ibus 终端输入:sudo apt-get install ibus ibus-clutter ibus-gtk ibus-gtk3 ibus-qt4 启动 ibus 终端输入 :  im-s ...

  5. Verilog实现IIC通讯第二版

    HMC5883三轴磁力传感器IIC通讯模块的VerilogHDL的实现 上一版并没有实现我想要的功能 0.0.1版   正在修订中   2013/9/2 //date :2013/7/7 //desi ...

  6. 基于visual Studio2013解决C语言竞赛题之0506选择排序

     题目

  7. c++ - Create empty json array with jsoncpp - Stack Overflow

    python中multiprocessing.pool函数介绍_正在拉磨_新浪博客     multiprocessing.pool c++ - Create empty json array wit ...

  8. 一步一步重写 CodeIgniter 框架 (5) —— 实现Controller,并加载Model

    CodeIgniter 框架采用MVC模式,而MVC模式中起纽带作用的就是C(控制器),在控制器的中通过加载模型获得数据,将数据传到视图中进行展示.本课将实现在控制器中加载模型. 1. 控制器的实现 ...

  9. 敲入url到浏览器后会发生什么

    浏览器连接DNS服务器,向url服务器请求把url转换为IP地址 DNS服务区返回URL的ip地址 浏览器建立一个TCP链接到web服务器80端口 web服务器发回的html代码 浏览器的渲染器根据h ...

  10. Qt线程QThread简析(8个线程等级,在UI线程里可调用thread->wait()等待线程结束,exit()可直接退出线程,setStackSize设置线程堆栈,首次见到Qt::HANDLE,QThreadData和QThreadPrivate)

    QThread实例代表一个线程,我们可以重新实现QThread::run(),要新建一个线程,我们应该先继承QThread并重新实现run()函数. 需要注意的是: 1.必须在创建QThread对象之 ...