观察者模式(C++实现)
观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一主题对象,在主题对象的状态发生变化时,会通知所有的观察者。
观察者模式角色如下:
抽象主题(Subject)角色:抽象主题角色提供维护一个观察者对象集合的操作方法,对集合的增加、删除等。
具体主题(ConcreteSubject)角色:将有关状态存入具体的观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发通知。具体主题角色负责实现抽象主题中的方法。
抽象观察者(Observer)角色:为具体观察者提供一个更新接口。
具体观察者(ConcreteObserver)角色:存储与主题相关的自洽状态,实现抽象观察者提供的更新接口。
Case:
在教室里老师还没有来,同学都在干着各的事情,小张正在打游戏,小李正在抄作业....., 现在同学们要求班长当卧底,监视老师,当老师来了通知大家一声。然后打游戏的马上停止,抄作业的也停止。
这里班长相当于是一个通知者, 小张、小李,以及其他同学显然是监听者,他们监听了班长那的消息,一旦老师来了马上采取相关的行动。
首先,先把通知者的行为抽象为一个接口:(subject)
class INotifier { public: virtual void registerListenner(ITeacherListenner *l) =0 ; virtual void removeListenner(ITeacherListenner *l) =0 ; virtual void notify() =0 ; };
第二,然后班长作为一个具体的通知者:(ConcreteSubject)
class MonitorNotifier:public INotifier { public: void registerListenner(ITeacherListenner *l) { listenners.push_back(l); }
void removeListenner(ITeacherListenner *l) { list<ITeacherListenner*>::iterator it; for(it=listenners.begin();it!=listenners.end();it++) { if(*it == l) { listenners.remove(l); break; } } }
void notify() { list<ITeacherListenner*>::iterator it; for(it=listenners.begin();it!=listenners.end();it++) { (*it)->onTecherComming(mValue;);
}
}
void setValue(int value)
{
mValue = value;
notify();
}
private:
list<ITeacherListenner*> listenners;
int mValue;
};
第三, 定义一个监听者的接口,想要监听老师来了这个消息的同学必须要实现这个接口:
class ITeacherListenner { public: virtual void onTecherComming(int value) = 0;
};
第四,ZhangSan 和 LiSi 监听了老师来了这个接口:
class ZhangSan:public ITeacherListenner { public: void onTecherComming(int value) { stopCopyWork(value); } void stopCopyWork(int value) { cout<<"zhangsan stopCopyWork + "<<value<<endl; } }; class LiSi:public ITeacherListenner { public: void onTecherComming(int value) { stopPlayGame(value); } void stopPlayGame(int value) { cout<<"lisi stopPlayGame + "<<value<<endl; } };
int main() { cout << "Hello World1-------------"<<endl; MonitorNotifier monitor; ZhangSan zs; LiSi ls; monitor.registerListenner(&zs); monitor.registerListenner(&ls); monitor.setValue(1); cout << "Hello World2-------------"<<endl; monitor.removeListenner(&ls); monitor.setValue(2); return 0; }
运行结果如下:
Hello World1-------------
zhangsan stopCopyWork + 1
lisi stopPlayGame + 1
Hello World2-------------
zhangsan stopCopyWork + 2
最后:完整的Demo(下载后删掉.sh)