观察者模式应用环境
当一个对象被多个对象所依赖,而且这一个对象发生改变时,需要通知那多个对象。并且这种改变经常发生。
UML结构图
- Subject(抽象主题):提供增加(Attach)、删除(Detach)、通知(Notify)观察者的接口。
- Observer(抽象观察者):提供自我更新(Updata)的接口。
- ConcreteSubject(具体主题):实现增加(Attach)、删除(Detach)、通知(Notify)观察者的接口。定义状态变量(subjectstate),以及设置状态(setstate)、获取状态(getstate)的函数
- ConcreteObserver(具体观察者):实现 Observer 所要求的更新接口,以便使本身的状态与主题的状态相协调。
例子
老师给学生布置作业
如果在放假期间,老师想要给学生们布置作业。如果学生一个一个打电话问老师,老师可能还没有想好要不知什么作业,而且布置了作业也可能会改动,所以学生就需要隔一段时间去问一下老师,确定作业有没有改变,这样效率比较低。如果老师将所有学生的电话号都记下来,有作业就直接群发短息,作业改动也群发短信,这样就十分高效。
代码:
#include<iostream>
#include<list>
#include<string>
using namespace std;
class Observer_Student{//抽象观察者(学生)
public:
virtual void Updata(const string& str) = 0;//更新作业
virtual ~Observer_Student(){}
};
class Subject_Teacher{//抽象主题(老师)
public:
virtual void Attach(Observer_Student *observer) = 0; //注册观察者
virtual void Detach(Observer_Student *observer) = 0; //注销观察者
virtual void Notify() = 0; //通知观察者
virtual ~Subject_Teacher(){}
};
class Student : public Observer_Student{//具体观察者 (学生)
public:
void Updata(const string& str){
homework = str;
}
virtual void print_homework(){
cout << homework << endl;
}
private:
string homework;
};
class English_Teacher : public Subject_Teacher{//具体主题(英语老师)
public:
void set_homework(const string& str){//设置作业
homework = str;
}
void Attach(Observer_Student *observer){//将学生添加进队列
L_observers.push_back(observer);
}
void Detach(Observer_Student *observer){//将学生移除队列
L_observers.remove(observer);
}
void Notify(){
for(auto it = L_observers.begin(); it != L_observers.end(); ++it){
(*it)->Updata(homework);//将作业更新给每一个同学
}
}
private:
list<Observer_Student *> L_observers;//观察者队列
string homework;//作业
};
int main(){
English_Teacher englishteacher;//实例化一个英语老师
Student student_1;//实例化学生1
Student student_2;//实例化学生2
Observer_Student* P_student_1 = &student_1;
Observer_Student* P_student_2 = &student_2;
englishteacher.Attach(P_student_1);//将学生的电话号加入电话博
englishteacher.Attach(P_student_2);
englishteacher.set_homework("今天没有作业");//设置作业
englishteacher.Notify();//群发消息
student_1.print_homework() ;//打印出作业,为了验证作业是否更新
return 0;
}
结果:
今天没有作业
总结:
观察者模式的实现,除了巧妙的逻辑关系以外,重要的是,观察者与主题之间通过各自的抽象进行耦合,实现松耦合。是多态与虚函数的典型应用。