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一般為純虛,通過子類各自實(shí)現(xiàn),這里只是保證調(diào)用的接口一致,Listener中的attach、remove、notify一般建議不進(jìn)行虛化,子類不用關(guān)心其內(nèi)部的聚合內(nèi)容,通過調(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ù),通過同一個(gè)條件進(jìn)行更新時(shí)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C++類與對(duì)象的重點(diǎn)知識(shí)點(diǎn)詳細(xì)分析
類和對(duì)象是兩種以計(jì)算機(jī)為載體的計(jì)算機(jī)語言的合稱。對(duì)象是對(duì)客觀事物的抽象,類是對(duì)對(duì)象的抽象。類是一種抽象的數(shù)據(jù)類型;變量就是可以變化的量,存儲(chǔ)在內(nèi)存中—個(gè)可以擁有在某個(gè)范圍內(nèi)的可變存儲(chǔ)區(qū)域2023-02-02
C++簡(jiǎn)單又輕松的講解類和對(duì)象中友元函數(shù)
采用類的機(jī)制后實(shí)現(xiàn)了數(shù)據(jù)的隱藏與封裝,類的數(shù)據(jù)成員一般定義為私有成員,成員函數(shù)一般定義為公有的,依此提供類與外界間的通信接口。但是,有時(shí)需要定義一些函數(shù),這些函數(shù)不是類的一部分,但又需要頻繁地訪問類的數(shù)據(jù)成員,這時(shí)可以將這些函數(shù)定義為該類的友元函數(shù)2022-06-06
C語言數(shù)據(jù)類型枚舉enum全面詳解示例教程
生活中有很多地方會(huì)用到枚舉,比如一周有7天,可以一一枚舉;性別有男、女...等等都可以可以一一枚舉,今天來和筆者一起學(xué)習(xí)一下c語言枚舉吧2021-10-10
OpenCV實(shí)現(xiàn)霍夫變換直線檢測(cè)
這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)霍夫變換直線檢測(cè),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
C語言線性表順序存儲(chǔ)結(jié)構(gòu)實(shí)例詳解
這篇文章主要介紹了C語言線性表順序存儲(chǔ)結(jié)構(gòu)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06

