观察者模式:
观察者模式有时也称为发布订阅-模式、模型-视图模式、源-收听者模式或从属者模式,是行为模式之一,其作用是当一个对象的状态发生变化时,能够自动通知其他关联对象,自动刷新对象状态。
观察者模式为关联对象提供了一种同步通信的手段,使某个对象与依赖它的其他对象之间保持状态同步。
观察者模式完美地将观察者和被观察的对象分离开。例如:用户界面可以作为一个观察者,业务数据可以作为被观察者,用户界面观察业务数据的变化,发现数据变化后,就能显示在用户界面上,面向对象设计的一个原则是:系统中的每个类将重点放在某一个功能上,而不是在其他方面,一个对象只做一件事情,并将它做好。观察者模式在模块之间划定了清晰的界限,提高应用程序的可维持性和重用性。
观察者设计模式定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都能得到通知并自动刷新。
观察者模式中角色组成如下:
(1)Subjict(被观察者类):它是被观察的对象,当被观察对象的状态发生变化时,需要通知队列中所有观察者对象,Subject需要维持(添加、删除、通知)一个观察者对象的的队列列表。
(2)Concrete Subject(具体的被观察对象):被观察者的具体实现,包含一些基本的属性状态及其他操作。
(3)Observer(观察者类):接口或抽象类,当Subjict的状态发生变化时,Observer将通过一个callback函数得到通知。
(4)Concrete Observer(具体观察者对象):观察者的具体实现,得到通知后将完成一些具体的业务逻辑处理。
例如,在公司上班的时候,有的员工在看电影、聊天,他们希望有个人能帮助他们查看老板的状态。如果老板来了,就通知他们老板过来了,他们就好好工作;如果老板走了也告诉他们,他们就可以继续干自己的事情。
这时我们可以让老板的秘书作为观察者,当她发现老板的状态变化时就通知员工,但秘书需要知道哪些员工需要接受消息,这步操作可以通过注册来完成,员工向秘书注册,则秘书将拥有一份通知名单。对应地,注册当然有取消注册,这就像邮件上的订阅与取消订阅、微博上的关注与取消关注一样。
#include<iostream>
#include<list>
#include<string>
using namespace std;
class Observer;
//抽象的通知者
class Subject
{
public:
virtual void notify(string info)=0;//将消息发送给所有观察者
virtual void add(Observer *)=0;//添加观察者
virtual void remover(Observer *)=0;//移除观察者
protected:
list<Observer *>m_list;
};
//抽象的观察者
class Observer
{
public:
virtual void update(string info)=0;//根据提供的消息进行自我更新
virtual void subscribe(Subject *)=0;//关注、注册、找个对象通知自己消息
virtual void disscribe(Subject *)=0;//取消关注
};
//通知者:秘书
class Secretary:public Subject
{
public:
void add(Observer *o)
{
m_list.push_back(o);
}
void remover(Observer *o)
{
m_list.remove(o);
}
void notify(string info)
{
//挨个通知
for(list<Observer *>::iterator it=m_list.begin();it!=m_list.end();it++)
{
(*it)->update(info);
}
}
};
class PlayGame:public Observer
{
public:
void subscribe(Subject *s)
{
s->add(this);
}
void disscribe(Subject *s)
{
s->remover(this);
}
void update(string info)
{
if(info=="老板来了")
{
cout<<"把游戏收起来,假装好好工作"<<endl;
}
else if(info=="老板走了")
{
cout<<"继续玩游戏"<<endl;
}
}
};
class SeeMovie:public Observer
{
public:
void subscribe(Subject *s)
{
s->add(this);
}
void disscribe(Subject *s)
{
s->remover(this);
}
void update(string info)
{
if(info=="老板来了")
{
cout<<"把游戏收起来,假装好好工作"<<endl;
}
else if(info=="老板走了")
{
cout<<"继续玩游戏"<<endl;
}
}
};
int main()
{
Subject *s=new Secretary;
Observer *w1=new PlayGame;
Observer *w2=new SeeMovie;
w1->subscribe(s); //告诉秘书,老板来了通知一声
w2->subscribe(s);
s->notify("老板来了");
return 0;
}