天天看點

設計模式(二十二)觀察者模式 C++

當對象間存在一對多關系時,則使用觀察者模式(Observer Pattern)。比如,當一個對象被修改時,則會自動通知它的依賴對象。觀察者模式屬于行為型模式。

觀察者模式所做的内容就是解耦

應用場景之一就是資料中心和多個業務單元的分離

設計模式(二十二)觀察者模式 C++

實作方式就是每一個觀察者都要儲存一個被觀察者的指針。

#include <iostream>
#include "string"
#include "list"
using namespace std;

class Secretary;

class Observer
{ 
public:
  virtual void update(string&) = 0;
};

class PlayserObserver :public Observer//觀察者
{
public:
  PlayserObserver(Secretary *secretary)
  {
    this->m_secretary = secretary;
  }

  void update(string& action)
  {
    cout << "action:" << action << endl;
    
  }

private:
  Secretary *m_secretary;
};

class Secretary
{
public:
  Secretary()
  {
    m_list.clear();
  }

  void Notify(string info)
  {
    //給所有的 觀察者 發送 情報
    for (list<Observer *>::iterator it = m_list.begin();
      it != m_list.end(); it++)
    {
      (*it)->update(info);
    }
  }

  void setPlayserObserver(Observer *o)
  {
    m_list.push_back(o);
  }

private:
  list<Observer *> m_list;
};

void main()
{
  Secretary            *secretary = NULL;
  PlayserObserver        *po1 = NULL;
  PlayserObserver        *po2 = NULL;

  secretary = new Secretary;
  po1 = new PlayserObserver(secretary);
  po2 = new PlayserObserver(secretary);

  secretary->setPlayserObserver(po1);
  secretary->setPlayserObserver(po2);

  secretary->Notify("老闆來了");
  secretary->Notify("老闆走了");
  delete secretary;
  delete po1;
  delete po2;

  system("pause");
  return;
}      
#include<list>
#include <string>
#include <iostream>

class IWorkerManager
{
public:

  virtual void OnCustom() = 0;
};

typedef std::list<IWorkerManager*> ListWorker;

class INotifyer
{
public:

  virtual void RegisterObserver(IWorkerManager *pWorkerManager) = 0;

  virtual void UnRegisterObserver(IWorkerManager *pWorkerManager) = 0;

  virtual void NotifyeObserver() = 0;
};

class DataControlModule :public INotifyer
{
public:
  DataControlModule::DataControlModule()
  {
  }

  DataControlModule::~DataControlModule()
  {
  }

  void DataControlModule::RegisterObserver(IWorkerManager *pWorkerManager)
  {
    m_listWorker.push_back(pWorkerManager);
  }
  void DataControlModule::UnRegisterObserver(IWorkerManager *pWorkerManager)
  {
    m_listWorker.remove(pWorkerManager);
  }
  void DataControlModule::NotifyeObserver()
  {
    ListWorker::iterator iterWorker = m_listWorker.begin();
    for (; iterWorker != m_listWorker.end(); iterWorker++)
    {
      IWorkerManager* pWorker = *iterWorker;

      pWorker->OnCustom();

      //(*iterWorker)->OnCustom();
    }

  }

  void DataControlModule::setNewData(const char* pszNewValue)
  {
    m_strData = pszNewValue;

    NotifyeObserver();
  }

  void DataControlModule::getNewData(std::string &strOutInfo)
  {
    strOutInfo = m_strData;
  }

private:

  ListWorker m_listWorker; // 觀察者清單

  std::string m_strData;
};

class WorkerModule :public IWorkerManager
{
public:

  WorkerModule(DataControlModule* pData, const char*pszInfo)
    :m_pdata(pData), m_strInfo(pszInfo)
  {
  }

  ~WorkerModule()
  {
  }

  void WorkerModule::OnCustom()
  {
    std::string strData;
    m_pdata->getNewData(strData);

    std::cout << " WorkerName:   " << m_strInfo.c_str() << std::endl;

    std::cout << "Got Data:  " << strData.c_str() << std::endl;
  }

private:

  DataControlModule* m_pdata;
  std::string m_strInfo;
};

int main()
{
  DataControlModule m_Data;
  WorkerModule m_worker1(&m_Data, "KAKA");
  WorkerModule m_worker2(&m_Data, "MESSE");
  WorkerModule m_worker3(&m_Data, "INZAGHI");

  m_Data.RegisterObserver(&m_worker1);
  m_Data.RegisterObserver(&m_worker2);
  m_Data.RegisterObserver(&m_worker3);

  m_Data.setNewData("Champion");
  system("pause");
  return 0;
}