观察者模式(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)

posted @ 2019-03-14 20:30  YOUNG++  阅读(10517)  评论(0编辑  收藏  举报