学习设计模式--观察者模式(C++)

来源:互联网 发布:mac appstore下载路径 编辑:程序博客网 时间:2024/04/25 15:00

转自:http://blog.csdn.net/moxiaomomo/article/details/7614627

1. 说说简单的函数回调

首先说说一种简单的函数回调机制(一种通过获取对象的指针来进行函数的调用方法)下面是代码演示---

这是观察者(被回调)部分:

[cpp] view plaincopy
  1. class Observer  
  2. {  
  3. public:  
  4.     // 抽象观察者的纯虚函数  
  5.     virtual void UpdateMessage() = 0;  
  6. };  
  7.   
  8. class ConcreteObserver : public Observer  
  9. {  
  10. public:  
  11.     // 实现抽象类的纯虚函数  
  12.     void UpdateMessage();  
  13. }  
  14.   
  15. void ConcreteObserver::UpdateMessage()  
  16. {  
  17.     // 这里实现具体的操作  
  18. }  
  19.   
  20. class Subject  
  21. {  
  22. public:  
  23.     Subject(Observer* observer = NULL);  
  24.       
  25.     void OnMessageChanged();  
  26.       
  27. private:  
  28.     Observer* m_observer;  
  29. };  

下面是被观察者(主动调用)部分:

[cpp] view plaincopy
  1. Subject::Subject(Observer* observer)  
  2. {  
  3.     // 将Observer的对象指针传进来并复制  
  4.     m_observer = observer;  
  5. }  
  6.   
  7. void Subject::OnMessageChanged()  
  8. {  
  9.     if(m_observer)  
  10.     {  
  11.         // 通过多态机制下的指针回调观察者的函数  
  12.         m_observer->UpdateMessage();  
  13.     }  
  14. }  
如上所示,程序中的一个对象通过获取另一个对象的指针,来进行函数的调用。这不是类之间的直接调用,只因该对象指针是在多态下定义的。

进一步拓展,如果有一个或多个多个观察者来关注一个或多个对象,那么就可以用通常所说的观察者模式来实现了。


2. 观察者模式的应用场合和特点

观察者模式一般出现在这样的场合:存在观察者和被观察对象。具体例子,比如订阅邮件或杂志, 微博关注某某主题等。当你在微博上关注了某个主题后,当这个主题有新的信息发出来时,你的微博主页将会相应收到它的更新信息。

而观察者模式提供了这样的一个对象模型,使得对象们(主题和观察者)之间松耦合:

(1)观察者的更替或数据模块的更新不会影响主题的存在。

(2)观察者和主题类可以方便的独立地被程序其他模块使用。

(3)一个主题可以注册多个观察者,也可以动态删除观察者; 一个观察者也可以注册多个主题,也可以撤销注册。

     例如一份天气预报可以被多个用户订阅,当数据更新时会通知所有注册的用户。一个用户也可以订阅多份天气预报,广州的,珠海的等等。


3.简单的代码演示

(1)演示的功能可以用这个类图来表达,类图中定义了Subject和Observer两个接口,并定义了两个具体主题类和三个具体观察者类。


(2)具体代码实现

首先是主题类,分别定义了类ConcreteSubjectA和类ConcreteSubjectB。

[cpp] view plaincopy
  1. class Subject  
  2.  {   
  3.  public:   
  4.      virtual void registerObserver(shared_ptr<Observer> observer) = 0;   
  5.      virtual void removeObserver(shared_ptr<Observer> observer) = 0;   
  6.      virtual void notifyObserver() = 0;   
  7.  };  
  8.    
  9.  class ConcreteSubjectA : public Subject  
  10.  {   
  11.  public:   
  12.       ConcreteSubjectA()   
  13.      {   
  14.          // do something here  
  15.          testValue = 1;  
  16.      }  
  17.    
  18.      void registerObserver(shared_ptr<Observer> observer)   
  19.      {   
  20.          observersList.push_back(observer);   
  21.      }   
  22.      void removeObserver(shared_ptr<Observer> observer)   
  23.      {   
  24.          observersList.remove(observer);   
  25.      }  
  26.    
  27.      void notifyObserver()   
  28.      {   
  29.          for (list<shared_ptr<Observer> >::iterator it = observersList.begin();   
  30.              it != observersList.end(); ++it)   
  31.          {   
  32.              (*it)->updateData(testValue);   
  33.          }   
  34.      }  
  35.    
  36.  private:   
  37.      list<shared_ptr<Observer> > observersList;   
  38.      int testValue;  
  39.  };  
  40.    
  41.  class ConcreteSubjectB : public Subject  
  42.  {   
  43.  public:   
  44.       ConcreteSubjectB()   
  45.      {   
  46.          // do something here  
  47.          testValue = 2;  
  48.      }  
  49.    
  50.      void registerObserver(shared_ptr<Observer> observer)   
  51.      {   
  52.          observersList.push_back(observer);   
  53.      }   
  54.      void removeObserver(shared_ptr<Observer> observer)   
  55.      {   
  56.          observersList.remove(observer);   
  57.      }  
  58.    
  59.      void notifyObserver()   
  60.      {   
  61.          for (list<shared_ptr<Observer> >::iterator it = observersList.begin();   
  62.              it != observersList.end(); ++it)   
  63.          {   
  64.              (*it)->updateData(testValue);   
  65.          }   
  66.      }  
  67.    
  68.  private:   
  69.      list<shared_ptr<Observer> > observersList;   
  70.      int testValue;  
  71.  };  
接着是观察者类,分别定义了类ConcreteObserverA,类ConcreteObserveB,类ConcreteObserverC。
[cpp] view plaincopy
  1. class Observer   
  2.  {   
  3.  public:   
  4.      virtual void updateData(int val) = 0;   
  5.  };  
  6.    
  7.  class ConcreteObserverA : public Observer   
  8.  {   
  9.  public:   
  10.      void updateData(int val)   
  11.      {   
  12.         // do something here  
  13.          cout << "In A :" << val <<endl;   
  14.      }   
  15.  };  
  16.    
  17.  class ConcreteObserverB : public Observer   
  18.  {   
  19.  public:   
  20.      void updateData(int val)   
  21.      {   
  22.         // do something here  
  23.          cout << "In B :" << val <<endl;   
  24.      }   
  25.  };  
  26.    
  27.  class ConcreteObserverC : public Observer   
  28.  {   
  29.  public:  
  30.      void updateData(int val)   
  31.      {   
  32.         // do something here  
  33.          cout << "In C :" <<val <<endl;   
  34.      }   
  35.  };  

然后,我们可以这样使用他们:
[cpp] view plaincopy
  1. int main()   
  2. {   
  3.     shared_ptr<Subject> subjectA(new ConcreteSubjectA());   
  4.     shared_ptr<Subject> subjectB(new ConcreteSubjectB());   
  5.    
  6.     shared_ptr<Observer> observerA(new ConcreteObserverA());   
  7.     shared_ptr<Observer> observerB(new ConcreteObserverB());   
  8.     shared_ptr<Observer> observerC(new ConcreteObserverC());   
  9.   
  10.     subjectA->registerObserver(observerA);   
  11.     subjectA->registerObserver(observerB);   
  12.     subjectB->registerObserver(observerC);   
  13.    
  14.  // 主题A有更新时将通知观察者A,B  
  15.     subjectA->notifyObserver();  
  16.  // 主题B有更新时将通知观察者C  
  17.  subjectB->notifyObserver();  
  18.   
  19.     return 0;