設計模式----Observer模式

pamxy發表於2013-06-24

轉自:http://blog.csdn.net/fly542/article/details/6716825

在以下任一情況下可以使用觀察者模式:

1、當一個抽象模型有兩個方面,其中一個方面依賴於另一個方面。將這二者封裝在獨立的物件中以使他們可以各自獨立的改變和複用

2、當對一個物件的改變需要同時改變其他物件,而不知道具體有多少物件有待改變。

3、當一個物件必須通知其它物件,而它又不能假定其它物件是誰。(即:不希望這些物件是緊密耦合的)

 

 

結構思想個人理解核心內容,要想記住這個模式簡單的方式就記住三個迴圈箭頭,從右下開始ConcreteObserver----->ConcreteSubject-------->Subject-------->Observer。

首先說明的是,此模式主要是想通過一個物件改變通知其他物件(observer物件)改變。

訊息的激發主要是由Subject的notify函式激發,至於什麼時候呼叫notify函式,可以自由設定(1、自動激發,2、客戶維護激發時機)

 

  1. #include <QtCore/QCoreApplication>  
  2.   
  3. #include <QList>  
  4.   
  5. class Subject;  
  6.   
  7. class Observer  
  8. {  
  9. public:  
  10.     virtual ~Observer();  
  11.     virtual void Update(Subject* theChangedSubject) = 0;  
  12. protected:  
  13.     Observer(); /// >防止例項化  
  14. };  
  15.   
  16. class Subject  
  17. {  
  18. public:  
  19.     virtual ~Subject();  
  20.     virtual void Attach(Observer * o){ m_observers.append(o);}  
  21.     virtual void Detach(Observer * o){ m_observers.removeOne(o);}  
  22.     virtual void Notify()  
  23.     {  
  24.         for(int i=0; i<m_observers.size(); ++i)  
  25.         {  
  26.             m_observers.at(i)->Update(this);  
  27.         }  
  28.     }  
  29.   
  30. protected:  
  31.     Subject(); /// >防止例項化  
  32.   
  33. private:  
  34.     QList<Observer*> m_observers;  
  35. };  
  36.   
  37. class ClockTimer : public Subject  
  38. {  
  39. public:  
  40.     ClockTimer();  
  41.   
  42.     void Tick(); /// 每tick一次激發一次notify  
  43. };  
  44.   
  45. void ClockTimer::Tick()  
  46. {  
  47.     Notify();  
  48. }  
  49.   
  50. class DigitalClock : public QWidget , public Observer  
  51. {  
  52. public:  
  53.     DigitalClock(ClockTimer*);  
  54.     virtual ~DigitalClock();  
  55.   
  56.     virtual void Update(Subject *theChangedSubject);  
  57.   
  58.     virtual void Draw();  
  59.   
  60.   
  61. private:  
  62.     ClockTimer * m_subject;  
  63. };  
  64.   
  65. DigitalClock::DigitalClock(ClockTimer *s)  
  66. {  
  67.     m_subject = s;  
  68.     m_subject->Attach(this);  
  69. }  
  70.   
  71. DigitalClock::~DigitalClock()  
  72. {  
  73.     m_subject->Detach(this);  
  74. }  
  75.   
  76. void DigitalClock::Update(Subject *theChangedSubject)  
  77. {  
  78.     if(m_subject == theChangedSubject)  
  79.     {  
  80.         Draw();  
  81.     }  
  82. }  
  83.   
  84. void DigitalClock::Draw()  
  85. {  
  86.     //// >繪製時間指標等內容  
  87. }  
  88.   
  89. /// 類似的建立另一個clock為AnalogClock  
  90.   
  91. class AnalogClock  
  92. {  
  93. public:  
  94.     AnalogClock(ClockTimer*);  
  95.     virtual ~AnalogClock();  
  96.   
  97.     virtual void Update(Subject *theChangedSubject);  
  98.   
  99.     virtual void Draw();  
  100.   
  101.   
  102. private:  
  103.     ClockTimer * m_subject;  
  104. };  
  105.   
  106. ///..... AnalogClock 的實現  
  107.   
  108.   
  109. int main(int argc, char *argv[])  
  110. {  
  111.     QCoreApplication a(argc, argv);  
  112.   
  113.     ClockTimer * timer = new ClockTimer;  
  114.     AnalogClock * aClock = new AnalogClock(timer);  
  115.     DigitalClock * dClock = new DigitalClock(timer);  
  116.   
  117.     /// >則兩個時鐘總是顯示相同的時間,都通過timer來同事更新  
  118.     return a.exec();  
  119. }  

相關文章