zoukankan      html  css  js  c++  java
  • 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 << "
    portal detached mail reader" << endl;
      pPortal->Detach(pMailReader);
      cout << "portal observers count: " << pPortal->GetObserversCount() << endl << endl;
      pPortal->Publish("门户分享设计模式");
      system("pause");
      return 0;
      }


  • 相关阅读:
    sklearn 数据预处理1: StandardScaler
    Gitlab利用Webhook实现Push代码后的Jenkins自动构建
    Shell脚本-自动化部署WEB
    Jenkins可用环境变量以及使用方法
    Docker常用命令
    nginx中root和alias的区别
    gitlab+jenkins=自动化构建
    Spring Boot2.0:使用Docker部署Spring Boot
    Maven内置属性、POM属性
    navicat连接mysql出现Client does not support authentication protocol requested by server解决方案
  • 原文地址:https://www.cnblogs.com/blfshiye/p/4296154.html
Copyright © 2011-2022 走看看