• 设计模式之观察者模式学习笔记


    1、定义 

    定义对象间的一种一对多的依赖关系 ,让多个观察者对象同时监听某一个主题对象,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新,又叫发布-订阅(publish-subscribe)模式。 


    2、解决问题

    在以下任一情况下可以使用观察者模式:
    (1)当一个抽象模型有两个方面 ,其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
    (2)当对一个对象的改变需要同时改变其它对象 , 而不知道具体有多少对象有待改变。
    (3)当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之 , 你不希望这些对象是紧密耦合的。 

    3、模式结构图

    Observer:抽象观察者,是观察者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
    ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。
    Subject (抽象主题,抽象通知者) :该角色是一个抽象类或接口,它把所有对观察者的引用保存在一个聚集里,每个通知者都可以有任何数量的观察者,定义了增加、删除、通知观察者对象的方法。
    ConcreteSubject(具体主题,具体通知者):将有关状态存入各ConcrereObserver对象,当它的状态发生改变时 , 向它的各个观察者发出通知。

     

    4、demo 

    (1)在教室里老师还没有来,同学都在干着各的事情,小张正在打游戏,小李正在抄作业,  现在同学们要求班长当卧底,监视老师,当老师来了通知大家一声。然后打游戏的马上停止,抄作业的也停止。
    这里班长相当于是一个通知者, 小张、小李,以及其他同学显然是观察者,他们监听了班长那的消息,一旦老师来了马上采取相关的行动。

    (2)对同一组数据进行统计分析时候, 我们希望能够提供多种形式的表示 (例如以表格进行统计显示、柱状图统计显示、百分比统计显示等)。这些表示都依赖于同一组数据, 我们当然需要当数据改变的时候, 所有的统计的显示都能够同时改变。
     

    1. #include"iostream"
    2. #include"list"
    3. #include"string"
    4. using namespace std;
    5. class Subject;
    6. /*抽象观察者,为所有具体观察者定义一个接口,在得到主题的通知时更新自己
    7. 如,干着各种事情的同学*/
    8. class AbsObserver
    9. {
    10. public:
    11. AbsObserver(string name, Subject* sub)
    12. {
    13. this->name = name;
    14. this->subject = sub;
    15. }
    16. virtual void update(int value) = 0;
    17. protected:
    18. string name;
    19. Subject* subject;
    20. };
    21. /*具体观察者*/
    22. class PlayGameStu :public AbsObserver
    23. {
    24. public:
    25. PlayGameStu(string name, Subject* sub) :AbsObserver(name, sub) {}
    26. void update(int value)
    27. {
    28. stopPlayGame(value);
    29. }
    30. void stopPlayGame(int value)
    31. {
    32. cout << name << "stopPlayGame" << endl;
    33. }
    34. };
    35. class CopyWorkStu :public AbsObserver
    36. {
    37. public:
    38. CopyWorkStu(string name, Subject* sub) :AbsObserver(name, sub) {}
    39. void update(int value)
    40. {
    41. stopCopyWork(value);
    42. }
    43. void stopCopyWork(int value)
    44. {
    45. cout << name << "stopCopyWork" << endl;
    46. }
    47. };
    48. //抽象主题,通知者、班长
    49. class Subject
    50. {
    51. public:
    52. virtual void addObserver(AbsObserver *observer) = 0;
    53. virtual void removeObserver(AbsObserver *observer) = 0;
    54. virtual void notify() = 0;
    55. void setState(int value)
    56. {
    57. stateTeacher = value;
    58. printf("当前状态:%d\n", value);
    59. notify();
    60. }
    61. protected:
    62. list observers;
    63. int stateTeacher; //老师状态
    64. };
    65. /*(具体主题,通知者、班长):该角色继承或实现了抽象主题,定义了一个集合存入注册过的具体观察者对象,
    66. 在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知*/
    67. class ConcreteSubject :public Subject
    68. {
    69. public:
    70. void addObserver(AbsObserver *observer)
    71. {
    72. observers.push_back(observer);
    73. }
    74. void removeObserver(AbsObserver *observer)
    75. {
    76. list::iterator it;
    77. for (it = observers.begin(); it != observers.end(); it++)
    78. {
    79. if (*it == observer)
    80. {
    81. observers.remove(observer);
    82. break;
    83. }
    84. }
    85. }
    86. void notify()
    87. {
    88. list::iterator it;
    89. for (it = observers.begin(); it != observers.end(); it++)
    90. {
    91. (*it)->update(stateTeacher);
    92. }
    93. }
    94. };
    95. int main()
    96. {
    97. //
    98. Subject* subject = new ConcreteSubject;
    99. AbsObserver* stuPG = new PlayGameStu("xiaoming", subject);
    100. AbsObserver* stuCW = new CopyWorkStu("xiaoli", subject);
    101. //
    102. subject->addObserver(stuPG);
    103. subject->addObserver(stuCW);
    104. subject->setState(1);
    105. subject->setState(2);
    106. return 0;
    107. }

     

  • 相关阅读:
    【SQL基础学习】----高级篇(1)
    异步为什么会造成 HTTP 队首阻塞?
    MyBatis
    [Android]打开应用时导航栏闪烁问题分析
    【回归预测】基于萤火虫算法优化模糊实现数据回归预测附matlab代码
    SQL SELECT 语句进阶
    NFS服务配置
    [山东科技大学OJ]2414 Problem G: 倒排字符串
    2023/10/5 下午3:38:53 SCROLLINFO scrollInfo;
    Mysql易错知识点整理(待更新)
  • 原文地址:https://blog.csdn.net/u012507022/article/details/126442827