觀察者模式定義物件間一對多依賴,主題狀態變更時自動通知所有觀察者更新。本文以 Excel 修改資料觸發折線圖/餅圖/長條圖同步重繪為切入點,詳解模式結構、協作時序、適用場景與 C++ 實作。
Update() 介面。Notify()。Update() 同步狀態。

Notify()。Update(state)。#include <iostream>
#include <list>
using namespace std;
class Observer {
public:
virtual void Update(int value) = 0;
virtual ~Observer() {}
};
class Subject {
public:
virtual void Attach(Observer *p) = 0;
virtual void Detach(Observer *p) = 0;
virtual void Notify() = 0;
virtual ~Subject() {}
};
class ConcreteObserver : public Observer {
Subject *m_pSubject;
public:
ConcreteObserver(Subject *p) : m_pSubject(p) {}
void Update(int value) override {
cout << "ConcreteObserver get update. New State: " << value << endl;
}
};
class ConcreteObserver2 : public Observer {
Subject *m_pSubject;
public:
ConcreteObserver2(Subject *p) : m_pSubject(p) {}
void Update(int value) override {
cout << "ConcreteObserver2 get update. New State: " << value << endl;
}
};
class ConcreteSubject : public Subject {
list<Observer*> m_observers;
int m_state;
public:
void Attach(Observer *p) override { m_observers.push_back(p); }
void Detach(Observer *p) override { m_observers.remove(p); }
void Notify() override {
for (auto *obs : m_observers) obs->Update(m_state);
}
void SetState(int s) { m_state = s; }
};
int main() {
ConcreteSubject *subj = new ConcreteSubject();
Observer *obs1 = new ConcreteObserver(subj);
Observer *obs2 = new ConcreteObserver2(subj);
subj->SetState(2);
subj->Attach(obs1); subj->Attach(obs2);
subj->Notify(); // 兩觀察者均收到 2
subj->Detach(obs1);
subj->SetState(3);
subj->Notify(); // 僅 obs2 收到 3
delete obs1; delete obs2; delete subj;
}
std::shared_ptr<Observer> 管理生命週期,避免懸空指標。std::function<void(int)> 替代虛擬介面,支援 Lambda 觀察者。Attach/Detach/Notify 需鎖保護(std::mutex)。boost::signals2、Qt Signal/Slot、std::experimental::observer_ptr(C++20 提案)。觀察者模式是 MVC、事件總線、反應式程式設計的基石。掌握其「主題-觀察者」解耦思想,能設計出擴展性強、測試友善的系統架構。