观察者模式

时间:2020-03-24
本文章向大家介绍观察者模式,主要包括观察者模式使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

班长是通知者,学生是观察者。看班长的通知,学生来行动。

  1 #define  _CRT_SECURE_NO_WARNINGS 
  2 #include <iostream>
  3 #include <string>
  4 #include <list>
  5 
  6 using namespace std;
  7 
  8 
  9 // 抽象的观察者, (监听者)
 10 class Listenner
 11 {
 12 public:
 13     //老师来了 我改怎么办
 14     virtual void onTeacherComming() = 0;
 15 
 16     //学生干坏事的方法
 17     virtual void doBadthing() = 0;
 18 };
 19 
 20 //抽象的 被观察者, (通知者)
 21 class Notifier
 22 {
 23 public:
 24     //添加观察者的方法
 25     virtual void addListenner(Listenner *listenner) = 0;
 26     //删除观察者的方法
 27     virtual void delListenner(Listenner *listenner) = 0;
 28 
 29     //通知所有观察者的方法
 30     virtual void notify() = 0;
 31 };
 32 
 33 //具体的观察者
 34 class Student :public Listenner
 35 {
 36 public:
 37     Student(string name, string badthing)
 38     {
 39         this->name = name; 
 40         this->badthing = badthing;
 41     }
 42 
 43     //老师来了学生该怎么办
 44     virtual void onTeacherComming()
 45     {
 46         cout << "学生"<<name  <<"发现班长给我使眼神了, 停止" << badthing << endl;
 47         cout << "改为写作业" << endl;
 48     }
 49 
 50     virtual void doBadthing() {
 51         cout << " 学生 " << name << "目前正在 " << badthing << endl;
 52     }
 53 private:
 54     string name;
 55     string badthing;
 56 };
 57 
 58 
 59 //具体的通知者(班长)
 60 class Monitor :public Notifier
 61 {
 62 public:
 63     //添加观察者的方法
 64     virtual void addListenner(Listenner *listenner)  {
 65         this->l_list.push_back(listenner);
 66     }
 67     //删除观察者的方法
 68     virtual void delListenner(Listenner *listenner)  {
 69         this->l_list.remove(listenner);
 70     }
 71 
 72     //通知所有观察者的方法
 73     //班长使眼神的方法
 74     virtual void notify()  {
 75         //广播信息,让每一个学生都执行各自的重写的onTeacherComming方法
 76         for (list<Listenner *>::iterator it = l_list.begin(); it != l_list.end(); it++) {
 77             (*it)->onTeacherComming();
 78             //在此处如果触发班长的notify()
 79         }
 80     }
 81 private:
 82     list<Listenner *> l_list; //班长手中所有的学生(观察者)
 83 };
 84 
 85 int main(void)
 86 {
 87     Listenner *s1 = new Student("张三", "抄作业");
 88     Listenner *s2 = new Student("李四", "打lol");
 89     Listenner *s3 = new Student("王五", " 看李四玩lol");
 90 
 91     Notifier *bossXu = new Monitor;
 92 
 93     //将所有的学生列表告知通知者,好让通知者进行通知 
 94     bossXu->addListenner(s1);
 95     bossXu->addListenner(s2);
 96     bossXu->addListenner(s3);
 97 
 98 
 99 
100     cout << "教师一片和谐,老师没有来 " << endl;
101     s1->doBadthing();
102     s2->doBadthing();
103     s3->doBadthing();
104 
105     cout << "班长突然发现老师来了,给学生们使了一个眼神" << endl;
106     bossXu->notify();
107 
108 
109 
110 
111     
112     return 0;
113 }

同帮派的人被人揍了,百晓生知道了,传播出去给每个人知道。被揍的人的同门不高兴了,要报仇。揍人的同门知道了,拍手叫好。

梳理这个代码如下:

  1 #define  _CRT_SECURE_NO_WARNINGS 
  2 #include <iostream>
  3 #include <string>
  4 #include <list>
  5 using namespace std;
  6 
  7 
  8 //前置声明notifier
  9 class Notifier;
 10 
 11 //抽象的观察者
 12 class Linstenner
 13 {
 14 public:
 15     //当朋友被揍了我改怎么办
 16     virtual void onFriendBeFight(Linstenner *one, Linstenner *another/*, Notifier *baixiao*/) = 0;
 17     //one是打别人的人, another 是被揍的
 18     virtual void fighting(Linstenner *another, Notifier *notifier) = 0;
 19 
 20     virtual string getName() = 0;
 21     virtual string getParty() = 0;
 22 };
 23 
 24 //抽象的通知者
 25 class Notifier
 26 {
 27 public:
 28     //添加观察者
 29     virtual void addListenner(Linstenner *listenner) = 0;
 30     //删除观察者
 31     virtual void delListenner(Linstenner *listenner) = 0;
 32 
 33     //通知观察者
 34     virtual void notify(Linstenner *one, Linstenner *another) = 0;
 35 };
 36 
 37 
 38 // 武林中的人物
 39 class Hero :public Linstenner
 40 {
 41 public:
 42     Hero(string name, string party)
 43     {
 44         this->name = name;
 45         this->party = party;
 46     }
 47 
 48     //当我发现一个消息之后我该怎么办
 49     virtual void onFriendBeFight(Linstenner *one, Linstenner *another/*, Notifier *baixiao*/)
 50     {
 51         if (another->getName() != this->name &&one->getName() != this->name) {
 52             //不是当事人
 53             //如果不是当事人,需要判断打人的pary 和 被打的party是不是我自己哥们
 54             if (one->getParty() == this->party) {
 55                 //自己人把 比人揍了
 56                 cout << name << "发现自己人把别人揍了, 笑了 , 拍手叫好" << endl;
 57             }
 58             else if (another->getParty() == this->party){
 59                 //自己人被揍了
 60                 cout << name << "发现自己人被别人走了, 出手援救" << endl;
 61                 //this->fighting(one, baixiao);
 62             }
 63         }
 64         else {
 65             //当事人
 66             //如果是当事人,什么都不敢
 67 
 68         }
 69     }
 70 
 71     //揍人的方法
 72     virtual void fighting(Linstenner *another, Notifier *notifier)
 73     {
 74         cout << name << "[" << this->party << "]" << "" 
 75             << another->getName() << "[" << another->getParty() << "]" << "给揍了" << endl;
 76 
 77       // 揍完之后,这个事件应该让百晓生知晓
 78         //应该调用百晓生 的notify方法
 79         notifier->notify(this, another);
 80     }
 81 
 82 
 83 
 84     string getName() {
 85         return this->name;
 86     }
 87 
 88     string getParty() {
 89         return this->party;
 90     }
 91 
 92 
 93 private:
 94     string name;
 95     string party;
 96 };
 97 
 98 
 99 class Baixiao :public Notifier
100 {
101 public:
102     //添加观察者
103     virtual void addListenner(Linstenner *listenner)  {
104         this->l_list.push_back(listenner);
105     }
106     //删除观察者
107     virtual void delListenner(Linstenner *listenner) {
108         this->l_list.remove(listenner);
109     }
110 
111     //通知观察者
112     virtual void notify(Linstenner *one, Linstenner *another)  {
113         for (list<Linstenner *>::iterator it = l_list.begin(); it != l_list.end(); it++) {
114             (*it)->onFriendBeFight(one, another/*, this*/);
115         }
116     }
117 private:
118     //拥有所有武林人士的名单
119     list<Linstenner*> l_list;
120 };
121 
122 int main(void)
123 {
124     Linstenner *hong7 = new Hero("洪七公", "丐帮");
125     Linstenner *huangrong = new Hero("黄蓉", "丐帮");
126     Linstenner *wuyazi = new Hero("无崖子", "逍遥派");
127     Linstenner *tonglao = new Hero("天山童姥", "逍遥派");
128 
129     //创建一个百晓生
130     Notifier *baixiao = new Baixiao;
131 
132     //百晓生 手机全部的武林人士名单
133     baixiao->addListenner(hong7);
134     baixiao->addListenner(huangrong);
135     baixiao->addListenner(wuyazi);
136     baixiao->addListenner(tonglao);
137 
138     
139 
140     //以上初始化完毕
141 
142     hong7->fighting(wuyazi, baixiao);
143 
144     cout << "----" << endl;
145     tonglao->fighting(hong7, baixiao);
146 
147 
148 
149     
150     return 0;
151 }

原文地址:https://www.cnblogs.com/strangemonkey/p/12561823.html