定义: 对象间的依赖关系,当一个对象变化,其他依赖对象也随之变化。
又称为 发布-订阅者模式。Publish/Subscribe
参与者:
Subject:目标,知道它的观察者,提供注册和删除观察者对象的接口
Observer:观察者,为那些在目标发生改变时需获得通知的对象定义一个更新接口
ConcreteSubject:具体目标,存储对象状态,状态改变时,向各个观察者发出通知
ConcreteObserver:具体观察者,维护一个指向ConcreteSubject对象的引用,存储有关状态,实现更新接口update,使自身状态与目标的状态保持一致
优缺点:
1 目标和观察者之间松耦合
2 支持广播通信:Subject发送的通知不需要指定它的接受者。通知被自动广播给所有已向该目标对象登记的有关对象。
3 意外的更新:看似无害的操作可能会引起观察者错误的更新。
demo /* * 观察者模式 * 情景:高数课,ABCD四位同学,A是好学生,去上课,B在寝室睡觉,C在网吧打游戏,D在学校外陪女友逛街 * 他们约定,如果要点名了,A在QQ群里吼一声,他们立刻赶到教室去。 * 采用观察者模式实现这个情景的应用。 */
#include <iostream>
#include <string>
#inlcude <list>
class Observer;
//目标
class Subject{
public:
virtual ~Subject(){};
virtual ~registerObsvr(Observer* obsvr) = 0;
virtual ~removeObsvr(Observer* obsvr) = 0;
};
//观察者
class Observer{
public:
virtual ~Observer(){};
virtual void Update(const std::string &msg) = 0;
virtual std::string getName() = 0;
protected:
Observer(){};
};
//--------------------------------------
//具体目标
class QQGroup: public Subject{
public:
QQGroup(){
_observers = new std::list<Observer*>();
}
void registerObsvr(Observer* obsvr);
void removeObsvr(Observer* obsvr);
void notifyObsvrs(const std::string &msg);
private:
std:list<Observer*> *_observers;
};
void QQGroup::registerObsvr(Observer* obsvr){
_observers->push_back(obsvr);
}
void QQGroup::removeObsvr(Observer* obsvr){
if(_observers->size() > 0)
_observers->remove(obsvr);
}
void QQGroup::notifyObsvrs(const std::string &msg){
std::cout << "群消息:" << msg << std::endl;
std::list<Observer*>::iterator iter
= _observers->begin();
for(; iter != _observers->end(); iter++){
(*iter)->Update(msg);
}
}
// ------------------
//具体观察者
class RoomMate : public Observer{
public:
RoomMate(std::string name, std::string now, std::string action)
{
_name = name;
_action = action;
_now = now;
}
void Update( const std::string &msg);
std::string getName();
private:
std::string _name;
std::string _action;
std::string _now;
};
std::string RoonMate::getName(){
return _name;
}
void RoomMate::Update(const std:: string &msg){
std::cout<< This is << _name << std::endl;
if(msg == "点名了")
cout << "Action:" << _action << endl;
else
cout << "Go on:" << _now << endl;
}
int main(){
RoomMate* B = new RoomMate("B", "sleeping", "get dressed and run to
classroom");
RoomMate* C = new RoomMate("C", "playing games","pay the fee and run
classroom");
RoomMate* D = new RoomMate("D",
"shopping with girl friend",
"go back to school and be worried about girl friend's angry");
QQGroup* qqgroup = new QQGroup();
qqgroup-> registerObsvr(B);
qqgroup-> registerObsvr(C);
qqgroup-> registerObsvr(D);
qqgroup-> notifyObsvrs("目前没点名");
qqgroup-> notifyObsvrs("点名");
return 0;
}