观察者模式
- 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- 观察者模式UML图:
例子
- 观察者:学生,他们正在观察目标(班长),老师没来,学生都在干坏事老师一来,班长给学生暗号,学生更新状态:都去写作业;
抽象观察者,及具体观察者
class AbstractObserver
{
public:
virtual void OnTeacherComing()=0;
virtual void DoBadThing() = 0;
};
class Student :public AbstractObserver
{
public:
Student(string name,string badthing)
{
m_name = name;
m_badthing = badthing;
}
virtual void DoBadThing() //老师没来应该干什么
{
cout << m_name << "正在 " << m_badthing << endl;
}
virtual void OnTeacherComing() //老师来了应该干什么
{
cout << m_name << " 正在学习" << endl;
}
private:
string m_name;
string m_badthing;
};
抽象观察目标,及具体目标
class AbstractSubject
{
public:
virtual void NotifyAllStudent() = 0;
virtual void DelStudent(AbstractObserver* student) = 0;
virtual void AddStudent(AbstractObserver* student) = 0;
};
class Monitor :public AbstractSubject //班长
{
public:
virtual void AddStudent(AbstractObserver* student) //添加观察者(学生)
{
m_list.push_back(student);
}
virtual void DelStudent(AbstractObserver* student)//删除观察者(学生)
{
m_list.remove(student);
}
virtual void NotifyAllStudent() //广播信息,老师来了,学生应该更新状态
{
list<AbstractObserver*>::iterator it = m_list.begin();
for (; it != m_list.end(); it++)
{
(*it)->OnTeacherComing();
}
}
private:
list<AbstractObserver*> m_list;
};
调用:
int main()
{
AbstractObserver* student1 = new Student("julian", "抄作业");
AbstractObserver* student2 = new Student("kerr", "谈恋爱");
AbstractObserver* student3 = new Student("jack", "打麻将");
AbstractSubject* monitor = new Monitor;
monitor->AddStudent(student1);
monitor->AddStudent(student2);
monitor->AddStudent(student3);
cout << "老师没有来,教室一片和谐" << endl;
student1->DoBadThing();
student2->DoBadThing();
student3->DoBadThing();
cout << "老师来了" << endl;
monitor->NotifyAllStudent();
return 0;
}
结果:学生都在干坏事同时观察班长,班长看到老师,通知学生,学生马上学习
- 优点:
(1) 观察者和被观察者是抽象耦合的
(2) 建立一套触发机制。
- 缺点:
(1)观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
(2)如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃
(3)如果一个观察目标对象有很多直接和间接观察者,将所有的观察者都通知到会花费很多时间
- 使用场景:
(1) 一个对象的改变将导致一个或多个其他对象也发生改变
(2) 一个对象必须通知其他对象,而并不知道这些对象是谁
(3) 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。