觀察者模式:
觀察者模式又叫分佈-訂閱模式
觀察者模式:定義了一種一對多的依賴關係,讓多個觀察者對象同時監聽某一個主題對象。這個主題對象在狀態發生變化時,會通知所有觀察者對象,使它們能夠自動更新自己。
觀察者模式(Observer)結構圖:
結構圖及觀察者模式結構代碼解釋:
Subject類:
可翻譯爲主題或抽象通知者,一般用一個抽象類或者一個接口實現。它把所有對觀察者對象的指針保存在一個集合裏,每個主題都可以有任何數量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者對象。
class Subject
{
private:
list<Observer *> observers = list<Observer *>();
public:
void Attach(Observer *observer)
{
observer.push_back(observer);
}
void Detach(observer * observer)
{
observers.remove(observer);
}
void Notify()
{
list<Observer *>::iteratorit=observer.begin();
for(;it!=observer.end();it++)
{
*it->Update();
}
}
};
Observer類:
抽象觀察者,爲所有的具體觀察者定義一個接口,在得到主題的通知時更新自己。這個接口叫做更新接口。抽象觀察者一般用一個抽象類或者一個接口實現。更新接口通過包含一個Update()函數,這個函數叫做更新方法。
class Observer
{
public:
void Update()=0;
};
ConcreteSubject類:
叫做具體主題或具體通知者,將有關狀態存入具體觀察者對象;在具體主題的內部狀態改變時,給所有登記過的觀察者發出通知。具體主題角色通常用一個具體子類實現。
class ConcreteSubject :public Subject
{
private:
String subjectState;
public:
String getSubjectState()
{
return subjectState;
}
void setSubjectState(String subjectState)
{
this->subjectState=subjectState;
}
}
ConcrereObserver類:
具體觀察者,實現抽象觀察者角色所要求的更新接口,以便使本身的狀態與主題的狀態相協調。具體觀察者角色可以保存一個指向具體主題對象的指針。具體觀察者角色通常用一個具體子類實現。
class ConcreteObserver :public Observer
{
private:
String name;
String observerState;
ConcreteSubject *subject;
public:
ConcreteObserver(ConcreteSubject *subject ,String name)
{
this->subject = subject;
this->name = name;
}
void Update()
{
observerState =subject->SubjectState;
cout<< “觀察者:”<<this->name<< “新狀態:”<<observerState<<endl;
}
};
客戶端代碼:
void main()
{
ConcreteSubject s;
ConcreteObserver * p1= newConcreteObserver(&s, “X”);
ConcreteObserver * p2= newConcreteObserver(&s, “Y”);
ConcreteObserver * p3= newConcreteObserver(&s, “Z”);
s.Attach(p1);
s.Attach(p2);
s.Attach(p3);
s.setSubjectState = “ABC”;
s.Notify();
}
結果顯示:
觀察者:X新狀態ABC
觀察者:Y新狀態ABC
觀察者:Z新狀態ABC
觀察者模式特點:
什麼時候應該使用觀察者模式:當一個對象的改變需要同時改變其他對象
而且它不知道具體有多少對象有待改變時,應該考慮使用觀察者模式。
觀察者模式所做的工作其實就是在解除耦合。讓耦合的雙方都依賴於抽象,而不是依賴於具體。從而使得各自的變化都有不影響另一邊的變化。