现在的位置: 首页 > 综合 > 正文

读《大话设计模式》---观察者模式(Observer)

2012年11月11日 ⁄ 综合 ⁄ 共 6912字 ⁄ 字号 评论关闭

观察者模式(Observer)又叫发布-订阅(Public/Subscribe)模式.
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个
主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

观察者模式的结构图

 

 

观察者模式一般实现:

  1. // Observer.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include "assert.h"
  5. #include <iostream>
  6. #include <string>
  7. #include <list>
  8. #include <algorithm>
  9. using namespace std;
  10. class Observer
  11. {
  12. private:
  13.  string name;
  14. public:
  15.  virtual bool operator==(const Observer obj) const
  16.  {
  17.   if(obj.name == name)
  18.    return true;
  19.   else
  20.    return false;
  21.  }
  22.  virtual void Update()
  23.  {
  24.   assert(false);
  25.  }
  26. };
  27. void fun(Observer * obj)
  28. {
  29.  obj->Update();
  30. }
  31. class Subject
  32. {
  33. private:
  34.  list<Observer*> observers;
  35.  //增加观察者
  36. public:
  37.  virtual void Attach(Observer *observer)
  38.  {
  39.   observers.push_back(observer);
  40.  }
  41.  //移除观察者
  42.  virtual void Detach(Observer *observer)
  43.  {
  44.   observers.remove(observer);
  45.  }
  46.  //通知
  47.  virtual void Notify()
  48.  {
  49.   for_each(observers.begin(), observers.end(), fun);
  50.  }
  51. };
  52. //具体通知者
  53. class ConcreteSubject : public Subject
  54. {
  55. private:
  56.  string subjectState;
  57.  //具体通知者状态
  58. public:
  59.  string GetSubjectState()
  60.  {
  61.   return subjectState; 
  62.  }
  63.  void SetsubjectState(string value)
  64.  { 
  65.   subjectState = value;
  66.  }
  67. };
  68. class ConcreteObserver : public Observer
  69. {
  70. private:
  71.  string name;
  72.  string observerState;
  73.  ConcreteSubject * subject;
  74. public:
  75.  ConcreteObserver(ConcreteSubject *_subject, const string &_name)
  76.  {
  77.   subject = _subject;
  78.   name = _name;
  79.  }
  80.  virtual bool operator==(const ConcreteObserver obj) const
  81.  {
  82.   if(obj.name == name)
  83.    return true;
  84.   else
  85.    return false;
  86.  }
  87.  //更新
  88.  virtual void Update()
  89.  {
  90.   observerState = subject->GetSubjectState();
  91.   cout << "观察者" << name << "的新状态是" << observerState << endl;
  92.  }
  93.  ConcreteSubject * GetConcreteSubject()
  94.  {
  95.   return subject;
  96.  }
  97.  SetConcreteSubject(ConcreteSubject * value)
  98.  {
  99.   subject = value; 
  100.  }
  101. };
  102. int main()
  103. {
  104.  //观察者模式
  105.  ConcreteSubject * CSub = new ConcreteSubject();
  106.  ConcreteObserver *ConcreteObserver1 = new ConcreteObserver(CSub, "X");
  107.  CSub->Attach(ConcreteObserver1);
  108.  ConcreteObserver *ConcreteObserver2 = new ConcreteObserver(CSub, "Y");
  109.  CSub->Attach(ConcreteObserver2);
  110.  ConcreteObserver *ConcreteObserver3 = new ConcreteObserver(CSub, "Z");
  111.  CSub->Attach(ConcreteObserver3);
  112.  CSub->SetsubjectState("ABC");
  113.  CSub->Notify();
  114.  delete ConcreteObserver1;
  115.  delete ConcreteObserver2;
  116.  delete ConcreteObserver3;
  117.  return 0;
  118. }

观察者模式的具体实现

 

 

 

  1. #include "stdafx.h"
  2. #include "assert.h"
  3. #include <iostream>
  4. #include <string>
  5. #include <list>
  6. #include <algorithm>
  7. using namespace std;
  8. class Observer;
  9. //通知者接口
  10. class Subject
  11. {
  12. private:
  13.  string action;
  14. public:
  15.  virtual void Attach(Observer * observer){};
  16.  virtual void Detach(Observer * observer){};
  17.  void Notify();
  18.  virtual string GetSubjectState(){assert(false);return 0;}
  19.  virtual void SetSubjectState(string &value ){assert(false);}
  20. };
  21. //观察者模式的特点:
  22. //将一个系统分割成一系
  23. //抽象观察者
  24. class Observer
  25. {
  26. protected:
  27.  string name;
  28.  Subject *sub;
  29. public:
  30.  Observer(string _name, Subject *_sub)
  31.  {
  32.   name = _name;
  33.   sub = _sub;
  34.  }
  35.  virtual bool operator==(const Observer obj) const
  36.  {
  37.   if(obj.name == name)
  38.    return true;
  39.   else
  40.    return false;
  41.  } 
  42.  virtual void Update(){cout << "Observer!" << endl; }
  43. };
  44. void fun(Observer *obj)
  45. {
  46.  obj->Update();
  47. }
  48. class Secretary : public Subject
  49. {
  50.  //同事列表
  51. private:
  52.  list<Observer*> observers;
  53.  string action;
  54.  //增加
  55. public:
  56.  virtual void Attach(Observer *observer)
  57.  {
  58.   observers.push_back(observer);
  59.  }
  60.  //减少
  61.  virtual void Detach(Observer *observer)
  62.  {
  63.   observers.remove(observer);
  64.  }
  65.  //通知
  66.  virtual void Notify()
  67.  {
  68.   for_each(observers.begin(), observers.end(), fun);
  69.  }
  70.  //前台状态
  71.  string GetSubjectState()
  72.  {
  73.   return action;
  74.  }
  75.  void SetSubjectState(string value )
  76.  {
  77.   action = value;
  78.  }
  79. };
  80. class Boss : public Subject
  81. {
  82.  //同事列表
  83. private:
  84.  list<Observer*> observers;
  85.  string action;
  86. public:
  87.  //增加
  88.  virtual void Attach(Observer *observer)
  89.  {
  90.   observers.push_back(observer);
  91.  }
  92.  //减少
  93.  virtual void Detach(Observer *observer)
  94.  {
  95.   observers.remove(observer);
  96.  }
  97.  //通知
  98.  virtual void Notify()
  99.  {
  100.   for_each(observers.begin(), observers.end(), fun);
  101.  }
  102.  //老板状态
  103.  virtual string GetSubjectState()
  104.  {
  105.   return action;
  106.  }
  107.  void SetSubjectState(string value)
  108.  {
  109.   action = value;
  110.  }
  111. };
  112. //看股票的同事
  113. class StockObserver : public Observer
  114. {
  115. public:
  116.  StockObserver(string name, Subject *sub)
  117.   : Observer(name, sub)
  118.  {
  119.  }
  120.  virtual void Update()
  121.  {
  122.   cout << sub->GetSubjectState() << name << "关闭股票行情,继续工作!" ;
  123.  }
  124. };
  125. //看NBA的同事
  126. class NBAObserver : public Observer
  127. {
  128. public:
  129.  NBAObserver(string name, Subject *sub)
  130.   : Observer(name, sub)
  131.  {
  132.  }
  133.  virtual void Update()
  134.  {
  135.   cout << sub->GetSubjectState() << name << "关闭NBA直播,继续工作!" ;
  136.  }
  137. };
  138. int main()
  139. {
  140.  //老板胡汉三
  141.  Boss * huhansan = new Boss();
  142.  //看股票的同事
  143.  StockObserver * Yangbailao = new StockObserver("杨白劳", huhansan);
  144.  //看NBA的同事
  145.  NBAObserver * Xier = new NBAObserver("喜儿", huhansan);
  146.  huhansan->Attach(Yangbailao);
  147.  huhansan->Attach(Xier);
  148.  huhansan->Detach(Yangbailao);
  149.  //老板回来
  150.  huhansan->SetSubjectState("我胡汉三回来了!");
  151.  //发出通知
  152.  huhansan->Notify();
  153.  return 0;
  154. }

观察者模式的不足


我们看观察者模式,发现抽象通知者和抽象观察者之间还有很大的耦合性。
这里我们可以通过使用委托来来解决这个问题
委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同
的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看作是
对函数的抽象,是函数的'类',委托的实例将代表一个具体的函数。
一个委托可以搭载多个方法,所有方法被依次唤起。可以使得委托对象所搭载的方法并不
属于同一个类。

 

  1. #include "stdafx.h"
  2. #include "assert.h"
  3. #include <iostream>
  4. #include <string>
  5. #include <list>
  6. #include <algorithm>
  7. using namespace std;
  8. class Observer;
  9. //通知者接口
  10. class Subject
  11. {
  12. private:
  13.  string action;
  14. public:
  15.  virtual void Attach(Observer * observer){};
  16.  virtual void Detach(Observer * observer){};
  17.  void Notify();
  18.  virtual string GetSubjectState(){assert(false);return 0;}
  19.  virtual void SetSubjectState(string &value ){assert(false);}
  20. };
  21. //通知者接口
  22. class Subject
  23. {
  24. public:
  25.  void Notify();
  26.  string GetSubjectState(){};
  27.  void SetSubjectState(){};
  28. };
  29. class StockObserver;
  30. typedef void (*EventHandler)();
  31. //事件处理程序的委托
  32. class Secretary : public Subject
  33. {
  34. //声明一事件Update,类型为委托EventHandler
  35. public:
  36.  void Update(EventHandler eh)
  37.  {
  38.   _eh = eh; 
  39.  }
  40.  void Notify()
  41.  {
  42.   (*_eh)();
  43.  }
  44.  string GetSubjectState()
  45.  {
  46.   return action;
  47.  }
  48.  void SetSubjectState(string value)
  49.  {
  50.   action = value;
  51.  } 
  52. private:
  53.  string action;
  54.  EventHandler _eh;
  55. };
  56. class Boss : public Subject
  57. {
  58.  //声明一事件Update,类型为委托EventHandler
  59. public:
  60.  void Update(EventHandler eh)
  61.  {
  62.   _eh = eh; 
  63.  }
  64.  void Notify()
  65.  {
  66.   (*_eh)();
  67.  }
  68.  string GetSubjectState()
  69.  {
  70.   return action;
  71.  }
  72.  void SetSubjectState(string value)
  73.  {
  74.   action = value;
  75.   cout << action << endl;
  76.  }
  77. private:
  78.  string action;
  79.  EventHandler _eh;
  80. };
  81. //看股票的同事
  82. class StockObserver
  83. {
  84. private:
  85.  string name;
  86.  Subject *sub;
  87. public:
  88.  StockObserver(string _name, Subject *_sub): name(_name), sub(_sub)
  89.  {
  90.  }
  91.  //关闭股票行情
  92.  static void CloseStockMarket()
  93.  {
  94.   cout << "关闭股票行情,继续工作!" ;
  95.  }
  96. };
  97. //看NBA的同事
  98. class NBAObserver
  99. {
  100. private:
  101.  string name;
  102.  Subject *sub;
  103. public:
  104.  NBAObserver(string _name, Subject *_sub): name(_name), sub(_sub)
  105.  {
  106.  }
  107.  //关闭NBA直播
  108.  static void CloseNBADirectSeeding()
  109.  {
  110.   cout << "关闭NBA直播,继续工作!";
  111.  }
  112. };
  113. int main()
  114. {
  115.  //老板胡汉三
  116.  Boss *huhansan = new Boss();
  117.  //看股票的同事
  118.  StockObserver * Yangbailao = new StockObserver("杨白劳", huhansan);
  119.  //看NBA的同事
  120.  NBAObserver * Xier = new NBAObserver("喜儿", huhansan);
  121.  //老板回来
  122.  huhansan->SetSubjectState("我胡汉三回来了!");
  123.  huhansan->Update(Yangbailao->CloseStockMarket);
  124.  //发出通知
  125.  huhansan->Notify();
  126.  huhansan->Update(Xier->CloseNBADirectSeeding); 
  127.  //发出通知
  128.  huhansan->Notify();
  129.  return 0;
  130. }

抱歉!评论已关闭.