觀察者模式,從字面上看,就是當觸發一件事情的時候,會做出相應的對策。被觀察者處在一個被監視的環境下。我們都知道臥底,就是一種抽象的觀察者模式。然而我們的項目中也大量的用到觀察者模式,比如:消息訂閱,監聽器。
首先,觀察者模式,需要有幾個角色,被觀察者,觀察者,以及業務實現。
抽象一個觀察類,被觀察者類,目標類,需要實現觀察者類,以及實現自己行爲抽象類,執行者需要實現觀察者類,當被觀察者有行動,通過拿到的觀察者抽象類,調用具體的實現類進行監控並給出結果。類圖如下:
其實線上系統,我們都是在多維度的進行消息通知,比如:訂票系統,不僅僅短信提醒,還要郵件提醒,日誌記錄等一系列的邏輯服務通知。
不過現在java已經支持觀察者模式了,對應的對象是Observable,Observer
我們看下Observable,這個被觀察者的類內部實現,下面是最重要的要的兩個屬性:
private boolean changed = false;改變的狀態。
private Vector<Observer> obs;所有的觀察者集合
我們就看兩個方法,第一個設置改變的變量爲true:
protected synchronized void setChanged() {
changed = true;
}
第二個通知,都很簡單,裏面還有增加,刪除觀察者方法:
public void notifyObservers(Object arg) {
/*
* a temporary array buffer, used as a snapshot of the state of
* current Observers.
*/
Object[] arrLocal;
synchronized (this) {
/* We don't want the Observer doing callbacks into
* arbitrary code while holding its own Monitor.
* The code where we extract each Observable from
* the Vector and store the state of the Observer
* needs synchronization, but notifying observers
* does not (should not). The worst result of any
* potential race-condition here is that:
* 1) a newly-added Observer will miss a
* notification in progress
* 2) a recently unregistered Observer will be
* wrongly notified when it doesn't care
*/
if (!changed)
return;
arrLocal = obs.toArray();
clearChanged();
}
for (int i = arrLocal.length-1; i>=0; i--)
((Observer)arrLocal[i]).update(this, arg);
}