为什么要有观察者模式
想象一个场景,有一只猫和一群老鼠,当猫出现的时候,每一只老鼠都要逃跑
用最简单的方法实现一个去模拟这一个过程
#include<iostream>
class Mouse_1
{
public:
void CatCome()
{
std::cout<<"Mouse_1 Run"<<std::endl;
}
};
class Mouse_2
{
public:
void CatCome()
{
std::cout<<"Mouse_2 Run"<<std::endl;
}
};
class Cat
{
public:
void IamCome()
{
std::cout<<"Cat Come!!!"<<std::endl;
mouse_1.CatCome();
mouse_2.CatCome();
}
private:
Mouse_1 mouse_1;
Mouse_2 mouse_2;
};
int main()
{
Cat cat;
cat.IamCome();
return 0;
}
执行后:
这么写的话,如果要多增加一只老鼠的话,那么就得把cat的类改为
class Cat
{
public:
void IamCome()
{
std::cout<<"Cat Come!!!"<<std::endl;
mouse_1.CatCome();
mouse_2.CatCome();
mouse_3.CatCome();
}
private:
Mouse_1 mouse_1;
Mouse_2 mouse_2;
Mouse_3 mouse_3;
};
这样的话每次修改都得修改Cat这个类,不是很方便,那么有没有一种模式可以不用修改这个类去实现添加老鼠的功能,那么就有了观察者模式
观察者模式的实现
首先我们需要定义一个接口,所有的老鼠继承这个接口:
class MosueInterface
{
public:
virtual void CatCome()=0;
virtual ~MosueInterface(){}
};
接着定义两只“mouse”:
class Mouse_1 : public MosueInterface
{
public:
void CatCome() override
{
std::cout<<"Mouse_1 Run"<<std::endl;
}
};
class Mouse_2 : public MosueInterface
{
public:
void CatCome() override
{
std::cout<<"Mouse_2 Run"<<std::endl;
}
};
接下来就要定义老猫了,首先需要一个vector能存储所有的老鼠:
std::vector<MosueInterface*> mice;
在老猫的方法里面定义添加修改这个vector的方法 :
//向vector中添加老鼠
void Add(MosueInterface* mouse)
{
mice.push_back(mouse);
}
//从vector中删除老鼠
void Remove(MosueInterface* mouse)
{
std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
if(it!=mice.end())
{
mice.erase(it);
}
}
遍历vector,挨个对老鼠发送“我来了的消息”:
void IamCome()
{
std::cout<<"Cat Come!!!"<<std::endl;
for(const auto i : mice)
{
i->CatCome();
}
}
老猫的总体定义如下:
class Cat
{
public:
void Add(MosueInterface* mouse)
{
mice.push_back(mouse);
}
void Remove(MosueInterface* mouse)
{
std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
if(it!=mice.end())
{
mice.erase(it);
}
}
void IamCome()
{
std::cout<<"Cat Come!!!"<<std::endl;
for(const auto i : mice)
{
i->CatCome();
}
}
private:
std::vector<MosueInterface*> mice;
};
在main中执行事件:
int main()
{
Cat cat;
cat.Add(new Mouse_1);
cat.Add(new Mouse_2);
cat.IamCome();
return 0;
}
整体代码如下
#include<iostream>
#include<vector>
#include<algorithm>
class MosueInterface
{
public:
virtual void CatCome()=0;
virtual ~MosueInterface(){}
};
class Mouse_1 : public MosueInterface
{
public:
void CatCome() override
{
std::cout<<"Mouse_1 Run"<<std::endl;
}
};
class Mouse_2 : public MosueInterface
{
public:
void CatCome() override
{
std::cout<<"Mouse_2 Run"<<std::endl;
}
};
class Cat
{
public:
//向vector中添加老鼠
void Add(MosueInterface* mouse)
{
mice.push_back(mouse);
}
//从vector中删除老鼠
void Remove(MosueInterface* mouse)
{
std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
if(it!=mice.end())
{
mice.erase(it);
}
}
void IamCome()
{
std::cout<<"Cat Come!!!"<<std::endl;
for(const auto i : mice)
{
i->CatCome();
}
}
private:
std::vector<MosueInterface*> mice;
};
int main()
{
Cat cat;
cat.Add(new Mouse_1);
cat.Add(new Mouse_2);
cat.IamCome();
return 0;
}
执行后:
这时候猫作为被观察者,老鼠作为观察者,这时候执行“我来了”的事件,就不需要每次都修改执行的代码了,只需要在主函数中添加即可
代码抽象出来
我们这时候想把这个观察者和被观察者抽象出来代码如下:
#include<iostream>
#include<vector>
#include<algorithm>
class MosueInterface
{
public:
virtual void CatCome()=0;
virtual ~MosueInterface(){}
};
class CatInterface{
public:
virtual void Add(MosueInterface* mouse)=0;
virtual void Remove(MosueInterface* mouse)=0;
virtual void IamCome()=0;
virtual ~CatInterface(){}
};
class Mouse_1 : public MosueInterface
{
public:
void CatCome() override
{
std::cout<<"Mouse_1 Run"<<std::endl;
}
};
class Mouse_2 : public MosueInterface
{
public:
void CatCome() override
{
std::cout<<"Mouse_2 Run"<<std::endl;
}
};
class Cat : public CatInterface
{
public:
void Add(MosueInterface* mouse) override
{
mice.push_back(mouse);
}
void Remove(MosueInterface* mouse) override
{
std::vector<MosueInterface*>::iterator it = std::find(mice.begin(),mice.end(),mouse);
if(it!=mice.end())
{
mice.erase(it);
}
}
void IamCome() override
{
std::cout<<"Cat Come!!!"<<std::endl;
for(const auto i : mice)
{
i->CatCome();
}
}
private:
std::vector<MosueInterface*> mice;
};
int main()
{
Cat cat;
cat.Add(new Mouse_1);
cat.Add(new Mouse_2);
cat.IamCome();
return 0;
}
在许多设计中,经常涉及多个对象都对一个特殊对象中的数据变化感兴趣,而且这多个对象都希望跟踪那个特殊对象中的数据变化,也就是说当对象间存在一对多关系时,在这样的情况下就可以使用观察者模式。当一个对象被修改时,则会自动通知它的依赖对象。
观察者模式是关于多个对象想知道一个对象中数据变化情况的一种成熟的模式。观察者模式中有一个称作“主题”的对象和若干个称作“观察者”的对象,“主题”和“观察者”间是一种一对多的依赖关系,当“主题”的状态发生变化时,所有“观察者”都得到通知。