特征
当一个对象状态改变时,该对象会通知到与之依赖的对象
目的
一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作
详情
观察者这里理解为时刻捕捉 状态变化后会对自己产生影响的对象,被捕捉的对象可以称它为被观察者,但这里并不是观察者自己察觉到被观察者的变化,而是被观察者当自身状态变更时主动通知给正在观察它的对象们。
打个比方,天要塌了,这时候天主动通知那些高的、壮的人去扛。天怎么知道自己要通知的是高的、壮的而不是矮子呢?一定是他们之间有着某些依赖联系,在这里,实际上就是那些高的、壮的有这个责任,因此他们时刻需要关注着天是否会塌,因此他们就是观察者,天就是被观察者。
class Person
{
void update();
}
class HighPerson:public Person
{
void update()
{
printf("我是高个,准备扛天");
}
}
class FatPerson:public Person
{
void update()
{
printf("我是壮汉,准备扛天");
}
}
class LittlePerson:public Person
{
void update()
{
printf("zzz。。。");
}
}
class Skyer
{
void bengEvent();//天塌事件
void notify();
void add(Person p);
void remove(Person p);
std::vector<Person> pList;
}
以上有高个、壮汉、瘦子三种人,他们都继承于Person,同时定义了skyer对象,也就是天。当skyer触发天塌事件时,应该调用notify函数去通知应该被通知的人,也就是高个和壮汉,因此我们通常会将这二者与天联系起来。
void Skyer::notify()
{
for(int i = 0; i < (int)pList.size(); ++i)
{
pList[i].update();
}
}
void Skyer::bengEvent()
{
notify();
}
void main()
{
Skyer sky = new Skyer();
Person p1 = new HighPerson();
Person p2 = new FatPerson();
Person p3 = new LittlePerson();
sky.add(p1);
sky.add(p2);
//随后sky等待天塌,也就是等待bengEvent被调用。
//......
}
不用理会语法,语法肯定有问题的,表达意思就行。
可以看到,skyer对象内部会将观察它的对象添加到自己的列表中,当自身塌时立刻通知到他们。
特殊情况:
如果观察者和被观察者关系太过亲密,也就是被观察者状态变化时会通知观察者做出反应,而该观察者做出的反应恰好又会触发被观察者的状态变化,往复循环。。。。
总结
可能我的理解不到位,欢迎大佬批评指正。
参考: