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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM