系列文章目錄
C++技能系列
Linux通信架構系列
C++高性能優(yōu)化編程系列
深入理解軟件架構設計系列
高級C++并發(fā)線程編程
設計模式系列
期待你的關注哦?。?!
現在的一切都是為將來的夢想編織翅膀,讓夢想在現實中展翅高飛。
Now everything is for the future of dream weaving wings, let the dream fly in reality.
一、觀察者模式介紹
?? 意圖:
定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。
?? 主要解決:
一個對象狀態(tài)改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協作。
?? 何時使用:
一個對象(目標對象)的狀態(tài)發(fā)生改變,所有的依賴對象(觀察者對象)都將得到通知,進行廣播通知。
?? 如何解決:
使用面向對象技術,可以將這種依賴關系弱化。
觀察者模式(Observer),又叫發(fā)布-訂閱模式(Publish/Subscribe):定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都要得到通知并自動更新。
觀察者模式從根本上講必須包含兩個角色:觀察者和被觀察對象。
被觀察對象自身應該包含一個容器來存放觀察者對象,當被觀察者自身發(fā)生改變時通知容器內所有的觀察者對象自動更新。
觀察者對象可以注冊到被觀察者的中,完成注冊后可以檢測被觀察者的變化,接收被觀察者的通知。當然觀察者也可以被注銷掉,停止對被觀察者的監(jiān)控。
二、觀察者模式優(yōu)缺點
2.1 優(yōu)點
-
觀察者和被觀察者是抽象耦合的。
-
建立一套觸發(fā)機制。
2.2 缺點
-
如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。
-
如果在觀察者和觀察目標之間有循環(huán)依賴的話,觀察目標會觸發(fā)它們之間進行循環(huán)調用,可能導致系統崩潰。
-
觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發(fā)生變化的,而僅僅只是知道觀察目標發(fā)生了變化。
三、觀察者模式使用場景
-
當一個抽象模型有兩個方面,其中一個方面依賴于另一方面。將這二者封裝在獨立的對象中以使它們可以各自獨立的改變和復用;
-
當對一個對象的改變需要同時改變其它對象,而不知道具體有多少對象有待改變;
-
當一個對象必須通知其它對象,而它又不能假定其它對象是誰;也就是說,你不希望這些對象是緊密耦合的。文章來源:http://www.zghlxwxcb.cn/news/detail-610551.html
四、觀察者模式實現
4.1 示例1 - 代碼實現
這里的目標 Subject 提供依賴于它的觀察者 Observer 的注冊( Attach) 和注銷( Detach)操作,并且提供了使得依賴于它的所有觀察者同步的操作( Notify)。 觀察者 Observer 則提供一個 Update 操作, 注意這里的 Observer 的 Update 操作并不在 Observer 改變了 Subject 目標狀態(tài)的時候就對自己進行更新, 這個更新操作要延遲到 Subject 對象發(fā)出 Notify 通知所有Observer 進行修改(調用 Update)。文章來源地址http://www.zghlxwxcb.cn/news/detail-610551.html
#include <iostream>
#include <string>
#include <list>
using namespace std;
class Subject;
//抽象觀察者
class Observer
{
protected:
string name;
Subject *sub;
public:
Observer(string name, Subject *sub)
{
this->name = name;
this->sub = sub;
}
virtual void update() = 0;
};
//具體的觀察者,看股票的
class StockObserver :public Observer
{
public:
StockObserver(string name, Subject *sub) :Observer(name, sub)
{
}
void update();
};
//具體的觀察者,看NBA的
class NBAObserver :public Observer
{
public:
NBAObserver(string name, Subject *sub) :Observer(name, sub)
{
}
void update();
};
//抽象通知者
class Subject
{
protected:
list<Observer*> observers;
public:
string action;
virtual void attach(Observer*) = 0;
virtual void detach(Observer*) = 0;
virtual void notify() = 0;
};
//具體通知者,秘書
class Secretary :public Subject
{
void attach(Observer *observer)
{
observers.push_back(observer);
}
void detach(Observer *observer)
{
list<Observer *>::iterator iter = observers.begin();
while (iter != observers.end())
{
if ((*iter) == observer)
{
observers.erase(iter);
}
++iter;
}
}
void notify()
{
list<Observer *>::iterator iter = observers.begin();
while (iter != observers.end())
{
(*iter)->update();
++iter;
}
}
};
void StockObserver::update()
{
cout << name << " 收到消息:" << sub->action << endl;
if (sub->action == "梁所長來了!")
{
cout << "我馬上關閉股票,裝做很認真工作的樣子!" << endl;
}
}
void NBAObserver::update()
{
cout << name << " 收到消息:" << sub->action << endl;
if (sub->action == "梁所長來了!")
{
cout << "我馬上關閉NBA,裝做很認真工作的樣子!" << endl;
}
}
int main()
{
Subject *dwq = new Secretary(); //創(chuàng)建觀察者<br> //被觀察的對象
Observer *xs = new NBAObserver("xiaoshuai", dwq);
Observer *zy = new NBAObserver("zouyue", dwq);
Observer *lm = new StockObserver("limin", dwq);
//加入觀察隊列
dwq->attach(xs);
dwq->attach(zy);
dwq->attach(lm);
//事件
dwq->action = "去吃飯了!";<br> //通知
dwq->notify();
cout << endl;
dwq->action = "梁所長來了!";
dwq->notify();
return 0;
}
4.1 示例2 - 代碼實現
#include <iostream>
#include <list>
using namespace std;
class Observer
{
public:
virtual void Update(int) = 0;
};
class Subject
{
public:
virtual void Attach(Observer *) = 0;
virtual void Detach(Observer *) = 0;
virtual void Notify() = 0;
};
class ConcreteObserver : public Observer
{
public:
ConcreteObserver(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
class ConcreteObserver2 : public Observer
{
public:
ConcreteObserver2(Subject *pSubject) : m_pSubject(pSubject){}
void Update(int value)
{
cout << "ConcreteObserver2 get the update. New State:" << value << endl;
}
private:
Subject *m_pSubject;
};
class ConcreteSubject : public Subject
{
public:
void Attach(Observer *pObserver);
void Detach(Observer *pObserver);
void Notify();
void SetState(int state)
{
m_iState = state;
}
private:
std::list<Observer *> m_ObserverList;
int m_iState;
};
void ConcreteSubject::Attach(Observer *pObserver)
{
m_ObserverList.push_back(pObserver);
}
void ConcreteSubject::Detach(Observer *pObserver)
{
m_ObserverList.remove(pObserver);
}
void ConcreteSubject::Notify()
{
std::list<Observer *>::iterator it = m_ObserverList.begin();
while (it != m_ObserverList.end())
{
(*it)->Update(m_iState);
++it;
}
}
int main()
{
// Create Subject
ConcreteSubject *pSubject = new ConcreteSubject();
// Create Observer
Observer *pObserver = new ConcreteObserver(pSubject);
Observer *pObserver2 = new ConcreteObserver2(pSubject);
// Change the state
pSubject->SetState(2);
// Register the observer
pSubject->Attach(pObserver);
pSubject->Attach(pObserver2);
pSubject->Notify();
// Unregister the observer
pSubject->Detach(pObserver);
pSubject->SetState(3);
pSubject->Notify();
delete pObserver;
delete pObserver2;
delete pSubject;
}
到了這里,關于行為型設計模式之觀察者模式【設計模式系列】的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!