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

来源:互联网 发布:阿里云vps如何购买 编辑:程序博客网 时间:2024/04/26 04:44

一、什么是观察者模式

Observer模式也叫观察者模式,是由GoF提出的23种软件设计模式的一种。Observer模式是行为模式之一,它的作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。

  观察者模式(Observer)完美的将观察者和被观察的对象分离开。举个例子,用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是其他方面。一个对象只做一件事情,并且将他做好。观察者模式在模块之间划定了清晰的界限,提高了应用程序的可维护性和重用性。

  观察者模式有很多实现方式,从根本上说,该模式必须包含两个角色:观察者和被观察对象。在刚才的例子中,业务数据是被观察对象,用户界面是观察者。观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。如果在用户界面、业务数据之间使用这样的观察过程,可以确保界面和数据之间划清界限,假定应用程序的需求发生变化,需要修改界面的表现,只需要重新构建一个用户界面,业务数据不需要发生变化。

  “观察”不是“直接调用”

  实现观察者模式的时候要注意,观察者和被观察对象之间的互动关系不能体现成类之间的直接调用,否则就将使观察者和被观察对象之间紧密的耦合起来,从根本上违反面向对象的设计的原则。无论是观察者“观察”观察对象,还是被观察者将自己的改变“通知”观察者,都不应该直接调用。

  实现观察者模式的形式

  实现观察者模式有很多形式,比较直观的一种是使用一种“注册——通知——撤销注册”的形式。

 

[cpp] view plaincopyprint?
  1. /************************************************************************/
  2. /* 观察者模式 */
  3. /************************************************************************/
  4. #include <LIST>
  5. #include <STRING>
  6. #include <iostream>
  7. using namespace std;
  8. /*
  9. 编程要点:观察者接口要有一个更新自身状态的行为
  10. 被观察者(主题):要有一个存放与之相联系的观察者的链表,并有一个通知的行为,当被观察者的状态发生改变时,
  11. 它会通知所有与之相关联地具体观察者,即调用与之关联的观察者的Update方法
  12. */
  13. class Subject;
  14. //观察者接口(抽象)
  15. class Observer{
  16. public:
  17. virtual ~Observer(){};
  18. virtual void Update(Subject *concreteSubject){};//根据被观察者更新自身状态
  19. };
  20. //被观察者(主题)
  21. class Subject
  22. {
  23. private:
  24. list<Observer*> *obvs;
  25. public:
  26. //构造函数
  27. Subject()
  28. {
  29. obvs = new list<Observer*>;
  30. }
  31. void Attach(Observer *observer)
  32. {
  33. obvs->push_front(observer);//向链表中加入一个待通知的观察者
  34. }
  35. void Detach(Observer *observer)
  36. {
  37. obvs->push_back(observer);//删除一个观察者
  38. }
  39. //通知每个观察者
  40. void Notify()
  41. {
  42. list<Observer*>::iterator it;
  43. it = obvs->begin();
  44. for(;it!=obvs->end();it++){
  45. (*it)->Update(this);//每个观察者被通知后更新自己的状态
  46. }
  47. }
  48. public:
  49. virtual char* getState(){return NULL;}
  50. virtual void setState(){}
  51. };
  52. /*具体的主题*/
  53. class ConcreteSubject :public Subject
  54. {
  55. private:
  56. char *state;//被观察者的状态
  57. public:
  58. /*被观察者自身状态的设置与获取*/
  59. char* getState()
  60. {
  61. return state;
  62. }
  63. void setState(char *state)
  64. {
  65. this->state = state;
  66. }
  67. };
  68. //具体的观察者
  69. class ConcreteObserverA : public Observer
  70. {
  71. private:
  72. char *name;//名称
  73. char *state;//状态
  74. public:
  75. ConcreteObserverA(char *name)
  76. {
  77. this->name = name;
  78. }
  79. void Update(Subject *concreteSubject)
  80. {
  81. state = concreteSubject->getState();//更新自身状态
  82. cout<<"观察者:"<<name<<"的新状态是:"<<state<<endl;
  83. }
  84. };
  85. void main()
  86. {
  87. //构造一个主题
  88. ConcreteSubject *concreteSubject = new ConcreteSubject();
  89. //让主题和观察者相联系
  90. concreteSubject->Attach(new ConcreteObserverA("X"));
  91. concreteSubject->Attach(new ConcreteObserverA("Y"));
  92. //主题状态改变,并通知观察者
  93. concreteSubject->setState("老师走了,大家可以玩了,哈哈");
  94. concreteSubject->Notify();
  95. printf("过了一段时间后........................\n");
  96. //主题状态改变,再次通知观察者
  97. concreteSubject->setState("老师来了,大家别说了");
  98. concreteSubject->Notify();
  99. }