C++設(shè)計(jì)模式之觀察者模式(Observer)
觀察者模式通常的叫法叫做訂閱-發(fā)布模式,類似于報(bào)刊雜志的訂閱,觀察者和被觀察者就是讀者和郵局的關(guān)系,讀者先要在郵局訂閱想要的報(bào)刊,當(dāng)報(bào)刊發(fā)行時(shí),郵局會(huì)將報(bào)刊郵寄到讀者家里。觀察者(Observer)和被觀察者(Listener)也是這種關(guān)系,Observer將自己attach到Listener中,當(dāng)Listener觸發(fā)時(shí)Notify所有Observer.
作用
在觀察者模式中,被觀察者維護(hù)觀察者對(duì)象的集合,當(dāng)被觀察者對(duì)象變化時(shí),它會(huì)通知觀察者。觀察者模式主要是用于解決對(duì)象之間一對(duì)多的關(guān)系。
類視圖

實(shí)現(xiàn)
class Observer
{
public:
virtual ~Observer() {};
virtual void Update(const std::string &msg)= 0;
protected:
Observer(){};
};
class Listener
{
public:
virtual ~Listener() {};
void attach(Observer* obsvr)
{
m_observers.push_back(obsvr);
}
void remove(Observer* obsvr)
{
m_observers.remove(obsvr);
}
void notify(const std::string &msg)
{
list<Observer*>::iterator iter = m_observers.begin();
for(; iter != m_observers.end(); iter++)
(*iter)->Update(msg);
}
private:
list<Observer* > m_observers; //觀察者鏈表
};
class logRunner : public Listener
{
public:
virtual ~logRunner(){};
void addmsg(const std::string &msg)
{
nofity(msg);
}
}
class logGui : public Observer
{
public:
virtual ~Observer(){};
void Update(const std::string &msg)
{
cout<< "Gui log show : "<< msg <<endl;
}
}
class logFile : public Observer
{
public:
virtual ~Observer(){};
void Update(const std::string &msg)
{
cout<< "file log write : "<< msg <<endl;
}
}
class logDebug : public Observer
{
public:
virtual ~Observer(){};
void Update(const std::string &msg)
{
cout<< "Debug log out : "<< msg <<endl;
}
}
class logDataBase : public Observer
{
public:
virtual ~Observer(){};
void Update(const std::string &msg)
{
cout<< "DataBase log in : "<< msg <<endl;
}
}
int main()
{
logRunner Runner;
logGui gGui;
logFile gFile;
logDebug gDebug;
logDataBase gDataBase;
Runner.attach(&gGui);
Runner.attach(&gFile);
Runner.attach(&gDebug);
Runner.attach(&gDataBase);
Runner.addmsg("app is setup");
}
Observer中update一般為純虛,通過(guò)子類各自實(shí)現(xiàn),這里只是保證調(diào)用的接口一致,Listener中的attach、remove、notify一般建議不進(jìn)行虛化,子類不用關(guān)心其內(nèi)部的聚合內(nèi)容,通過(guò)調(diào)用notify實(shí)現(xiàn)消息分發(fā)即可。當(dāng)然也可以虛化,將這一系列的操作放到子類進(jìn)行實(shí)現(xiàn)。
調(diào)用者應(yīng)該注意在多線程環(huán)境中的使用環(huán)境,做好數(shù)據(jù)的同步工作。
應(yīng)用場(chǎng)景
- 當(dāng)一個(gè)對(duì)象改變需要通知到其他對(duì)象,而我們不確定由多少對(duì)象需要通知時(shí);
- 當(dāng)一個(gè)對(duì)象必須通知其他對(duì)象,而不需要知道對(duì)象是什么實(shí)現(xiàn)時(shí);
- 對(duì)于一堆對(duì)象,包含同樣的狀態(tài)或同樣的數(shù)據(jù),通過(guò)同一個(gè)條件進(jìn)行更新時(shí)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
零基礎(chǔ)學(xué)習(xí)C/C++需要注意的地方
這篇文章主要介紹了零基礎(chǔ)學(xué)習(xí)C/C++需要注意的地方,文中講解非常細(xì)致,供大家參考和學(xué)習(xí),想要學(xué)習(xí)C/C++的可以閱讀此文2020-06-06
C語(yǔ)言實(shí)現(xiàn)求解素?cái)?shù)的N種方法總結(jié)
哈嘍各位友友們,今天又學(xué)到了很多有趣的知識(shí),現(xiàn)在迫不及待的想和大家分享一下!本文將手把手帶領(lǐng)大家探討利用試除法、篩選法求解素?cái)?shù)的n層境界!都是精華內(nèi)容,可不要錯(cuò)過(guò)喲2023-01-01
C++的std::transform()的實(shí)現(xiàn)
在 C++ 標(biāo)準(zhǔn)庫(kù)中,std::transform() 是一個(gè)非常有用的算法函數(shù),它能夠?qū)⒔o定范圍中的每個(gè)元素進(jìn)行變換,并將變換后的結(jié)果存儲(chǔ)到另一個(gè)范圍中,本文就詳細(xì)的介紹一下具體用法,感興趣的可以了解一下2023-08-08
C語(yǔ)言實(shí)現(xiàn)歌手比賽系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)歌手比賽系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
C++中指向?qū)ο蟮某V羔樑c指向常對(duì)象的指針詳解
如果一個(gè)變量已經(jīng)被聲明成常變量,則只能用指向常變量的指針變量指向它,而不能用一般的(非const型的)指針變量指向它2013-10-10

