在以下任一情況下可以使用觀察者模式:
1、當一個抽象模型有兩個方面,其中一個方面依賴於另一個方面。將這二者封裝在獨立的對象中以使他們可以各自獨立的改變和複用
2、當對一個對象的改變需要同時改變其他對象,而不知道具體有多少對象有待改變。
3、當一個對象必須通知其它對象,而它又不能假定其它對象是誰。(即:不希望這些對象是緊密耦合的)
結構思想個人理解核心內容,要想記住這個模式簡單的方式就記住三個迴圈箭頭,從右下開始ConcreteObserver----->ConcreteSubject-------->Subject-------->Observer。
首先說明的是,此模式主要是想通過一個對象改變通知其他對象(observer對象)改變。
訊息的激發主要是由Subject的notify函數激發,至於什麼時候調用notify函數,可以自由設定(1、自動激發,2、客戶維護激發時機)
#include <QtCore/QCoreApplication>#include <QList>class Subject;class Observer{public: virtual ~Observer(); virtual void Update(Subject* theChangedSubject) = 0;protected: Observer(); /// >防止執行個體化};class Subject{public: virtual ~Subject(); virtual void Attach(Observer * o){ m_observers.append(o);} virtual void Detach(Observer * o){ m_observers.removeOne(o);} virtual void Notify() { for(int i=0; i<m_observers.size(); ++i) { m_observers.at(i)->Update(this); } }protected: Subject(); /// >防止執行個體化private: QList<Observer*> m_observers;};class ClockTimer : public Subject{public: ClockTimer(); void Tick(); /// 每tick一次激發一次notify};void ClockTimer::Tick(){ Notify();}class DigitalClock : public QWidget , public Observer{public: DigitalClock(ClockTimer*); virtual ~DigitalClock(); virtual void Update(Subject *theChangedSubject); virtual void Draw();private: ClockTimer * m_subject;};DigitalClock::DigitalClock(ClockTimer *s){ m_subject = s; m_subject->Attach(this);}DigitalClock::~DigitalClock(){ m_subject->Detach(this);}void DigitalClock::Update(Subject *theChangedSubject){ if(m_subject == theChangedSubject) { Draw(); }}void DigitalClock::Draw(){ //// >繪製時間指標等內容}/// 類似的建立另一個clock為AnalogClockclass AnalogClock{public: AnalogClock(ClockTimer*); virtual ~AnalogClock(); virtual void Update(Subject *theChangedSubject); virtual void Draw();private: ClockTimer * m_subject;};///..... AnalogClock 的實現int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); ClockTimer * timer = new ClockTimer; AnalogClock * aClock = new AnalogClock(timer); DigitalClock * dClock = new DigitalClock(timer); /// >則兩個時鐘總是顯示相同的時間,都通過timer來同事更新 return a.exec();}