Observer.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /*
  2. * C++ Design Patterns: OBSERVER
  3. *
  4. * http://www.plantuml.com/plantuml/uml/XL51Rjim4Bpp5OFqaBY1xVOg24RWDeTS6Y0ESgUaTSo08bLoQTH8yvTUzGvzh9GYkguCj3nnPuOxiyiRpz9ngBLONk9-lRbzUBfzmELInACCazlAah09nGkLZ5U1UEROtnUUt9uSCZn5mhg1k8PabkNkIXdOI2NLR6Gh-XThBAljuUgz_81duWrBfYFW_m1lGfHQUeylrfIEcAO1_NizwAFLdU7HPDBr-gGhnDlfpCSHNqV_q5IzpYDB-vWXwnCm_U2pqCarmNTLmixJJwpci2DmbZ-5cFr_dDvcfoe2rGqVK5DTaFD2f5NDLnUV5ekF5pZvo-4B5FcZAFyvdq-NBDA3lzc4YeaS-Ra6MHen1egc1EdnxVCmGrwiyj9gwp9d3rAlTQ1LUfSl1sQLBujL4ZyU6ifw06lQoRsoJkg1-zgrMsKK8nY28orPMHCBTB_GwE0L1US7PME3W-jQgLNqWPQeuwNNlVICjgEkkeolovqqprIJuLXtBKjUuD463qqUDexCexXh6pALDEpXhU5nkLth8GFREiRv7eO-2n5rFKtY9jv2hNy3
  5. *
  6. * 2021 / JMB
  7. *
  8. */
  9. #include <iostream>
  10. #include <vector>
  11. class Subject;
  12. class Observer {
  13. public:
  14. Observer(const int id) : p_id(id) {}
  15. virtual ~Observer() {}
  16. virtual int getState() = 0;
  17. virtual void update(Subject* subject) = 0;
  18. virtual int getId() = 0;
  19. protected:
  20. int p_id;
  21. };
  22. class ConcreteObserver : public Observer {
  23. public:
  24. ConcreteObserver(const int state, const int id)
  25. : observerState(state), Observer(id) {}
  26. ~ConcreteObserver() {}
  27. int getState() {
  28. return observerState;
  29. }
  30. int getId() {
  31. return p_id; //protected
  32. }
  33. void update(Subject* subject);
  34. private:
  35. int observerState;
  36. };
  37. class Subject {
  38. public:
  39. virtual ~Subject() {}
  40. void attach(Observer* observer) {
  41. vObserver.emplace_back(observer);
  42. }
  43. void detach(const int id) {
  44. for (auto it = vObserver.begin(); it != vObserver.end(); ++it) {
  45. if ((*it)->getId() == id) {
  46. vObserver.erase(it);
  47. }
  48. }
  49. }
  50. void notify() {
  51. for (auto observer : vObserver) {
  52. observer->update(this);
  53. }
  54. }
  55. virtual int getState() = 0;
  56. virtual void setState(const int state) = 0;
  57. private:
  58. std::vector<Observer*> vObserver;
  59. };
  60. class ConcreteSubject : public Subject {
  61. public:
  62. ~ConcreteSubject() {}
  63. int getState() {
  64. return subjectState;
  65. }
  66. void setState(const int state) {
  67. subjectState = state;
  68. }
  69. private:
  70. int subjectState;
  71. };
  72. void ConcreteObserver::update(Subject *subject) {
  73. observerState = subject->getState();
  74. std::cout << "Observer(id=" << p_id << ") update state to: " << observerState << std::endl;
  75. }
  76. int main() {
  77. ConcreteObserver observer1(1000, 1);
  78. ConcreteObserver observer2(2000, 2);
  79. std::cout << "Observer1 state: " << observer1.getState() << std::endl;
  80. std::cout << "Observer2 state: " << observer2.getState() << std::endl;
  81. Subject* subject = new ConcreteSubject();
  82. subject->attach(&observer1);
  83. subject->attach(&observer2);
  84. subject->setState(10);
  85. subject->notify();
  86. std::cout << "Observer1 state: " << observer1.getState() << std::endl;
  87. std::cout << "Observer2 state: " << observer2.getState() << std::endl;
  88. subject->detach(1);
  89. subject->setState(100);
  90. subject->notify();
  91. std::cout << "Observer1 state: " << observer1.getState() << std::endl;
  92. std::cout << "Observer2 state: " << observer2.getState() << std::endl;
  93. }