[toc]

观察者模式定义

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。

气象站布告板设计

  1. #include <utility>
  2. #include "algorithm"
  3. #include "iostream"
  4. #include "vector"
  5. using namespace std;
  6. class Observer {
  7. public:
  8. // 所有的观察者都必须实现update方法
  9. virtual void update(float temp, float humidity, float pressure){};
  10. };
  11. class Subject {
  12. public:
  13. virtual void registerObserver(Observer *o) {}
  14. virtual void removeObserver(Observer *o) {}
  15. virtual void notifyObserver() {} // 主题改变时调用次方法,以通知所有的观察者
  16. };
  17. class DisplayElement {
  18. virtual void display() {}
  19. };
  20. // weatherdata 需要实现Subject接口
  21. class WeatherData : public Subject {
  22. private:
  23. vector<Observer *> observers;
  24. float temperature{};
  25. float humidity{};
  26. float pressure{};
  27. public:
  28. WeatherData() = default;
  29. void registerObserver(Observer *o) override { observers.push_back(o); }
  30. void removeObserver(Observer *o) override {
  31. for (auto iter = observers.begin(); iter != observers.end(); iter++) {
  32. if (*iter == o) {
  33. observers.erase(iter, iter + 1);
  34. break;
  35. }
  36. }
  37. }
  38. void notifyObserver() override {
  39. for (auto ob : observers) {
  40. ob->update(temperature, humidity, pressure);
  41. }
  42. }
  43. void measurementsChanged(float temp,float humi,float pressure) {
  44. this->temperature=temp;
  45. this->humidity=humi;
  46. this->pressure=pressure;
  47. notifyObserver();
  48. }
  49. };
  50. class CurrentConditionDisplay : public Observer, DisplayElement {
  51. private:
  52. float temperature{};
  53. float humidity{};
  54. Subject *weatherData;
  55. public:
  56. explicit CurrentConditionDisplay(Subject *wethData) {
  57. weatherData = wethData;
  58. weatherData->registerObserver(this);
  59. }
  60. void update(float temp, float humidity, float pressure) override {
  61. this->temperature=temp;
  62. this->humidity=humidity;
  63. display();
  64. }
  65. void display() override {
  66. cout<<"Current Condition: "<<temperature<<"F "<<" and "<<humidity<<endl;
  67. }
  68. };
  69. class StatisticsDisplay : public Observer, DisplayElement {
  70. private:
  71. float temperature{};
  72. float humidity{};
  73. Subject *weatherData;
  74. public:
  75. explicit StatisticsDisplay(Subject *wethData) {
  76. weatherData = wethData;
  77. weatherData->registerObserver(this);
  78. }
  79. void update(float temp, float humidity, float pressure) override {
  80. this->temperature=temp;
  81. this->humidity=humidity;
  82. display();
  83. }
  84. void display() override {
  85. cout<<"Statics Condition: "<<temperature<<"F "<<" and "<<humidity<<endl;
  86. }
  87. };
  88. int main() {
  89. cout << ">>>>>>>>>>>>>>>>>RUNNING on CLion<<<<<<<<<<<<<" << endl;
  90. auto *weatherData=new WeatherData();
  91. auto *currentDisplay=new CurrentConditionDisplay(weatherData);
  92. auto *staticsDisplay=new StatisticsDisplay(weatherData);
  93. weatherData->measurementsChanged(80,65,30.4);
  94. weatherData->measurementsChanged(82,70,29.3);
  95. weatherData->measurementsChanged(78,90,28.3);
  96. return 0;
  97. }