声明:本博文篇幅短,适合review。
一、概念
定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
二、模式结构图
class Observer;
class Subject
{
public:
virtual ~Subject();
virtual void attach(Observer * obsv){
mObsvs->push_front(obsv);
}
virtual void detach(Observer * obsv){
if (obsv != NULL){
mObsvs->remove(obsv);
}
}
virtual void notify(){
std::list<Observer *>::iterator it = mObsvs->begin();
for (; it != mObsvs->end(); it++){
(*it)->update(this);
}
}
virtual void setState(const std::string & str) = 0;
virtual std::string getState() = 0;
protected:
Subject(){
mObsvs = new std::list<Observer *>;
}
private:
std::list<Observer *> * mObsvs;
};
class ConcreteSubject : public Subject
{
public:
ConcreteSubject(){
mState = "";
}
~ConcreteSubject();
std::string getState(){
return mState;
}
void setState(const std::string & str){
mState = str;
}
private:
std::string mState;
};
class Observer
{
public:
virtual void update(Subject * sub) = 0;
};
class ConcreteObserverA : public Observer
{
public:
ConcreteObserverA(Subject * sub){
mSub = sub;
mSub->attach(this);
}
~ConcreteObserverA(){
mSub->detach();
}
void update(Subject * sub){
cout<<"ConcreteObserverA update : state---"<<sub->getState()<<endl;
}
private:
Subject * mSub;
};
class ConcreteObserverB : public Observer
{
public:
ConcreteObserverB(Subject * sub){
mSub = sub;
mSub->attach(this);
}
~ConcreteObserverB(){
mSub->detach();
}
void update(Subject * sub){
cout<<"ConcreteObserverB update : state---"<<sub->getState()<<endl;
}
private:
Subject * mSub;
};
void main(){
Subject * sub = new ConcreteSubject();
Observer * ob1 = new ConcreteObserverA(sub);
Observer * ob2 = new ConcreteObserverB(sub);
sub->setState("xxx");
sub->notify();
sub->setState("yyy");
sub->notify();
}
三、例子
class Boss;
class Staff
{
public:
virtual ~Staff();
virtual void attach(Boss * bs){
mBs->push_front(bs);
}
virtual void detach(Boss * bs){
if (bs != NULL){
mBs->remove(bs);
}
}
virtual void notify(){
std::list<Boss *>::iterator it = mBs->begin();
for (; it != mBs->end(); it++){
(*it)->update(this);
}
}
virtual void setState(const std::string & str) = 0;
virtual std::string getState() = 0;
protected:
Staff(){
mBs = new std::list<Boss *>;
}
private:
std::list<Boss *> * mBs;
};
class Receptionist : public Staff
{
public:
Receptionist(){
mState = "";
}
~Receptionist();
std::string getState(){
return mState;
}
void setState(const std::string & str){
mState = str;
}
private:
std::string mState;
};
class Boss
{
public:
virtual void update(Staff * stf) = 0;
};
class CTO : public Boss
{
public:
CTO(Staff * stf){
mStf = stf;
mStf->attach(this);
}
~CTO(){
mStf->detach();
}
void update(Staff * stf){
cout<<"CTO update : state---"<<stf->getState()<<endl;
}
private:
Staff * mStf;
};
class Manager : public Boss
{
public:
Manager(Staff * stf){
mStf = stf;
mStf->attach(this);
}
~Manager(){
mStf->detach();
}
void update(Staff * stf){
cout<<"Manager update : state---"<<stf->getState()<<endl;
}
private:
Staff * mStf;
};
void main(){
Staff * xiaoli = new Receptionist();
Boss * cto = new CTO(xiaoli);
Boss * manger = new Manager(xiaoli);
xiaoli->setState("有快递来啦~");
xiaoli->notify();
xiaoli->setState("有人来面试啦~");
xiaoli->notify();
}
四、优缺点
1、优点
a、降低了观察者与被观察者之间的耦合。
b、Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。
c、观察者模式支持广播通信。
2、缺点
a、观察者过多,存在效率问题。
b、松耦合可能导致关系不明确而不易理解。