定义
什么是观察者模式?观察者模式通俗的理解就是多个对象(观察者)“实时”观察某个对象(主题对象)。一旦这个被观察的对象状态发生了变化或者产生了某种事件,就会依次通知所有正在观察该对象的观察者,让他们能主动且及时应对状态(或事件)的发生。
1)观察者要想得主题对象的通知,必须在主题对象那里登记——添加观察者。
2)观察者不想继续得到主题对象的通知的时候,主题对象应该将其从自己的登记表中去除——删除观察者。
3)主题对象一般需要一个动态的容器作为登记表记录多个观察者,容器一般可以是vector、list。map等。
4)当主题对象的状态发生变化的时候要做的就是遍历该容器,“通知”容器中所有观察者(即调用某个观察者的事件处理函数)。
UML图
标题中的双解耦,其实就是定义了抽象的观察者Observer和抽象的主题Subject。然后让具体的观察者和具体的主题继承抽象接口。这样做的好处有两点:
1)抽象的Observert可以继承很多不同类的观察者,如观察者一想要得到“何时吃饭”的通知,观察者二想要得到“何时考试”通知
2)抽象的Subject可以继承不同类的主题(即通知者),如通知者是“妈妈”或者通知者是“老师”。
代码:
- class Observer
- {
- protected:
- Subject &subject;
- public:
- Observer(Subject &sub):subject(sub){}
- virtual void action()=0;
- };
- class son:public Observer
- {
- public:
- son(Subject &sub):Observer(&sub){}
- void action()
- {
- cout<<sub.GetState()<<",回家吃饭了\n";
- }
- }
- class Subject
- {
- public:
- virtual void Add(Observer &observer)=0;//定义抽象添加函数
- virtual void Delete(Observer &observer)=0;//定义抽象删除函数
- void Notify()=0;//定义抽象通知消息函数
- char* GetState()=0;//获取主题对象的状态
- };
- class Monther:public Subject
- {
- vector<Observer&> observers;//存放观察者的容器
- public:
- void Add(Observer &obs)
- {
- observers.push_back(obs);//添加一个观察者
- }
- void Delete(Observer &obs)
- {
- observers.pop_back(obs);//删除一个观察者
- }
- void Notify()
- {
- iterator vector<Observer&> it;
- for(it=observers.begin();it!=observers.end();++it)
- {
- it->action();//遍历通知所有观察者
- }
- }
- char* GetState()
- {
- return "我是妈妈";
- }
- }