观察者模式

1. 观察者模式

      当一个对象的状态发生变化时,通知者能够自动通知所有的观察者对象,自动刷新对象状态。
        其实就是:当 Subject(被观察者) 的状态发生变化时,Observer(观察者) 对象将通过一个 callback 函数 得到通知
      典型应用
           - 侦听事件驱动程序设计中的外部事件
           - 侦听/监视某个对象的状态变化
           - 发布者/订阅者(publisher/subscriber)模型中,当一个外部事件(新的产品,消息的出现等等)被触发时,通知邮件列表中的订阅者
        适用于:
             定义对象间一种一对多的依赖关系,使得每一个对象改变状态,则所有依赖于他们的对象都会得到通知。

2. 案例

        秘书:通知者(被观察者)
        员工:观察者
        让多个观察对象(公司员工)同时监听一个主题对象(秘书),主题对象状态发生变化时,会通知所有的观察者,使它们能够更新自己。
 1 #include <iostream>
 2 using namespace std;
 3 
 4 #include "vector"
 5 #include "string"
 6 
 7 class Secretary;
 8 
 9 //玩游戏的同事类(观察者)
10 class PlayserObserver
11 {
12 public:
13     PlayserObserver(string name, Secretary *secretary)
14     {
15         m_name = name;
16         m_secretary = secretary;
17     }
18     void update(string action)  //观察者通过此回调函数来得到通知
19     {
20         cout << "观察者收到 action:" << action << endl;
21     }
22 private:
23     string m_name;
24     Secretary *m_secretary;   //每一个观察者内部都有一个被观察者(通知者)
25 };
26 
27 //秘书类(主题对象,通知者,被观察者)
28 //被观察者当需要被观察的状态发生变化时,需要通知队列中所有观察者对象。需要维持(添加,删除,通知)一个观察者对象的队列列表。
29 class Secretary
30 {
31 public:
32     void addObserver(PlayserObserver *o)
33     {
34         v.push_back(o);
35     }
36     void Notify(string action)  //用来通知所有的观察者
37     {
38         for (vector<PlayserObserver *>::iterator it= v.begin(); it!=v.end(); it++ )
39         {
40             (*it)->update(action);  //调用观察者的回调函数
41         }
42     }
43     void setAction(string action)
44     {
45         m_action = action;
46         Notify(m_action);
47     }
48 private:
49     string m_action;
50     vector<PlayserObserver *> v;  //通知者(被观察者)维持一个观察者对象的队列列表
51 };
52 
53 int main()
54 {
55     //subject 被观察者(秘书)
56     Secretary *s1 = new Secretary;
57 
58     //具体的观察者 被通知对象
59     PlayserObserver *po1 = new PlayserObserver("小张", s1);
60     PlayserObserver *po2 = new PlayserObserver("小李", s1);
61 
62     s1->addObserver(po1);  //添加一个观察者到通知者的队列中
63     s1->addObserver(po2);  //添加一个观察者到通知者的队列中
64 
65     s1->setAction("老板来了");
66     s1->setAction("老板走了");
67 
68     return 0;
69 }

运行结果:

      

 

 

posted @ 2022-11-29 22:20  我就不告诉你我是谁  阅读(178)  评论(0编辑  收藏  举报