設計模式介紹之七:觀察者模式(observer)

    觀察者模式(又稱釋出/訂閱模式)定義物件間的一種一對多的依賴關係,當一個物件的狀態發生改變時,,所有依賴於它的物件都得到通知並被自動更新。

    常見的應用程式框架中有很多觀察者模式的應用,比如 MFC 的 Doc/View ,Qt 中的訊號與槽、 Model/View Architecture,安卓中的廣播接收者( Broadcast Receiver )。

    當對一個物件的改變需要同時改變其它物件,而不知道具體有多少物件有待改變;當一個物件必須通知其它物件,而它又不能假定其它物件是誰,換言之, 你不希望這些物件是緊密耦合的;……這些場景下都可以使用觀察者模式。

    下圖是觀察者模式的 UML 表示:

    下面提供一個觀察者模式的例項。這個例項描述的是這麼一個情況:有人想看花,希望花開的時候能夠得到通知。

    先看目標和觀察者介面的宣告:

class BloomObserver{
public:
BloomObserver();
virtual ~BloomObserver();
virtual void bloomed() = 0;
};
class Rose{
public:
Rose();
~Rose();
void attach(BloomObserver *pObserver);
void detach(BloomObserver *pObserver);
void notify();
void setBloomed();
bool bloomed();
private:
bool m_bBloomed;
BloomObserverList m_observers;
};

    再看目標的實現:

Rose::Rose():m_bBloomed(false)
{}
void Rose::attach(BloomObserver *pObserver){
m_observers.add(pObserver);
}
void Rose::detach(BloomObserver *pObserver){
m_observers.remove(pObserver);
}
void Rose::notify(){
foreach(BloomObserver *observer, m_observers)
observer->bloomed();
}
void Rose::setBloomed(){
m_bBloomed = true;
notify();
}
bool Rose::bloomed(){
return m_bBloomed;
}

    接下來是觀察者的實現:

class ObserverA : public BloomObserver{
void bloomed(){
callFriendsDriveCarToSomewhere();
}
};
class ObserverB : public BloomObserver{
void bloomed(){
writeBlog();
}
};
class ObserverC : public BloomObserver{
void bloomed(){
takeCameraToSomewhere();
}
};

    最後是驅動程式碼:

int main(int argc, char**argv){
Rose rose;
ObserverA *a = new ObserverA;
ObserverB *b = new ObserverB;
ObserverC *c = new ObserverC;
rose.attach(a);
rose.attach(b);
rose.attach(c);
//doSomethingHere();
rose.setBloomed();
rose.detach(a);
rose.detach(b);
rose.detach(c);
delete a; delete b; delete c;
return 0;
}

    好啦,以上就是觀察者模式的一個簡單實現。留心的人會在生活和軟體系統中發現觀察者模式的各種各樣的具體應用(比如電話留言、QQ好友上線通知、安卓中的各種 Listener 介面)。

    回顧一哈: