首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C++ 設計模式:觀察者模式完整解析與 Excel 圖表自動更新實例

     編輯:關於C語言

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

核心角色

  • Subject(主題):管理觀察者清單,提供註冊/移除/通知介面。
  • Observer(觀察者):定義 Update() 介面。
  • ConcreteSubject:儲存具體狀態,狀態變更時呼叫 Notify()。
  • ConcreteObserver:持有主題參考,實作 Update() 同步狀態。

UML 類別圖與時序圖

觀察者模式 UML

觀察者模式時序

協作流程

  1. ConcreteSubject 狀態變更 → 呼叫 Notify()。
  2. 遍歷觀察者清單,逐一呼叫 Update(state)。
  3. ConcreteObserver 可主動向 Subject 查詢細節以同步內部狀態。

適用場景

  1. 抽象模型有兩層,一層依賴另一層,封裝分離利於獨立變化與復用。
  2. 一個物件變更需同時改變其他物件,但不知具體有多少觀察者。
  3. 主題不應假定觀察者具體類別,避免緊耦合。

C++ 完整實作

#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;
}

現代 C++ 改良建議

  • 使用 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、事件總線、反應式程式設計的基石。掌握其「主題-觀察者」解耦思想,能設計出擴展性強、測試友善的系統架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved