一,理论学习:
1.什么叫观察者模式?
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖他的对象都得到通知并被自动更新!此模式通常用来实现事件处理系统。
2.观察者模式的组成:
2.1 观察者:观察者(例子中观察者为Subscribers)将自己注册到被观察者(例子中被观察者为Weather)中,被观察对象将观察者存放在一个容器(Container)里。
2.2 被观察者:被观察对象发生了某种变化(如我写的例子中天气的变化),从容器中得到所有注册过的观察者(如我写的例子中的订阅用户),将变化通知观察者。
3.实现观察者模式的要点说明:
在观察者模式的实现中,被观察者(Weather)维护一个vector作为储存其所有观察者对象(Subscribers)的容器,每当调用被观察者中的 Notify函数就遍历vector容器中的所有观察者对象,并调用观察者中的 Update函数改变观察者自身的状态。
4.观察者模式的应用场景:
4.1 当一个对象的改变需要同时改变其他对象的时候,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
4.2 观察者模式所做的工作其实就是在解除耦合。让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
二,观察者模式的C++代码实现:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class Weather;//被观察者:天气
class Subscribers //观察者:订阅用户
{
public:
Subscribers(string name,Weather*w)
{
this->name = name;
this->w = w;
}
void Update();
private:
string name;
Weather*w;
};
class Weather
{
public:
string Action1;
string Action2;
string Action3;
void Add(Subscribers sub)
{
Users.push_back(sub);
}
void Notify()
{
vector<Subscribers>::iterator p = Users.begin();
while (p != Users.end())
{
(*p).Update();
p++;
}
}
private:
vector<Subscribers> Users;
};
void Subscribers::Update()
{
cout << name << "用户您好!" << endl;
cout << w->Action1 << "今天白天晴,最高温度25度,今天夜间小雨,最低温度20度!" << endl;
cout << w->Action2 << "今天白天晴,最高温度30度,今天夜间小雨,最低温度25度!" << endl;
cout << w->Action3 << "今天白天阴,最高温度28度,今天夜间多云,最低温度20度!" << endl;
cout << "============================================================================" << endl;
}
int main(void)
{
//创建被观察者
Weather*p = new Weather();
//创建观察者
Subscribers*s1 = new Subscribers("小李", p);
Subscribers*s2 = new Subscribers("小明", p);
Subscribers*s3 = new Subscribers("小黄", p);
Subscribers*s4 = new Subscribers("小马", p);
Subscribers*s5 = new Subscribers("小罗", p);
Subscribers*s6 = new Subscribers("小邓", p);
//加入通知队列
p->Add(*s1);
p->Add(*s2);
p->Add(*s3);
p->Add(*s4);
p->Add(*s5);
p->Add(*s6);
//事件
p->Action1 = "贵阳实时天气预报:";
p->Action2 = "长沙实时天气预报:";
p->Action3 = "湘潭实时天气预报:";
//通知
p->Notify();
delete p;
delete s1;
delete s2;
delete s3;
delete s4;
delete s5;
delete s6;
system("pause");
return 0;
}
<pre>运行结果截图: