1.觀察者模式概述
1.1、意圖
定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴它的對象都得到通知並自動更新。
1.2、適用性
- 當一個抽象模型有兩個方面,其中一個方面依賴於另一方面。將這二者封裝在獨立的對象中以使他們可以各自獨立的改變和複用。
- 當對一個對象的改變需要同時改變其他對象,而不知道具體有多少對象有待改變。
- 當一個對象必須通知其他對象,而又不能確定其它對象是誰。
1.3、結構圖
- Subject類添加和刪除觀察者,可以有任意多個觀察者觀察同一個目標。
- Observer爲一個抽象接口類。
- ConcreteOberver爲具體的觀察者。
2.代碼示例
//Observer類
class MyProgress {
public:
virtual void doProgress(float fValue) = 0;
virtual ~MyProgress() {}
};
//ConcreteSubject
class DeleteFile {
public:
void doDeleteFile() {
for (int i = 0; i < 5; i++) {
onProgress((i + 1)*100 / 5.0);
}
}
void addProgress(MyProgress *pProgress){
m_progressList.push_back(pProgress);
}
void removeProgress(MyProgress *pProgress) {
m_progressList.remove(pProgress);
}
protected:
void onProgress(float fValue) {
for (auto progress : m_progressList) {
progress->doProgress(fValue);
}
}
private:
std::list<MyProgress*> m_progressList;
};
//ConcreteObserverA
class Widget : public MyProgress {
public:
virtual void doProgress(float fValue) {
std::cout << "widget progress:" << fValue <<"%"<< std::endl;
}
};
//ConcreteObserverB
class Dialog : public MyProgress {
public:
void btnClick(){
DeleteFile deleteFile;
Widget widget;
deleteFile.addProgress(&widget);
deleteFile.addProgress(this);
deleteFile.doDeleteFile();
}
virtual void doProgress(float fValue) {
std::cout << "dialog progress:" << fValue <<"%"<< std::endl;
}
};
int main()
{
Dialog dialog;
dialog.btnClick();
system("pause");
return 0;
}
輸出結果: