一、Observer模式的意圖:
在對象的內(nèi)部狀態(tài)發(fā)生變化時,自動通知外部對象進(jìn)行響應(yīng)。
二、Observer模式的構(gòu)成:
·被觀察者:內(nèi)部狀態(tài)有可能被改變,而且又需要通知外部的對象
·觀察者:需要對內(nèi)部狀態(tài)的改變做出響應(yīng)的對象
三、Observer模式的Java實現(xiàn):
Java的API中已經(jīng)為我們提供了Observer模式的實現(xiàn)。具體由java.util.Observable類和java.util.Observer接口完成。
前者有兩個重要的方法:
·setChanged:設(shè)置內(nèi)部狀態(tài)為已改變
·notifyObservers(Object obj):通知觀察者所發(fā)生的改變,參數(shù)obj是一些改變的信息
后者有一個核心方法:
·update(Object obj):相應(yīng)被觀察者的改變,其中obj就是被觀察者傳遞過來的信息,該方法會在notifyObservers被調(diào)用時自動調(diào)用。
下面是Observer模式的實現(xiàn)過程:
·創(chuàng)建一個被觀察者,繼承java.util.Observable
·創(chuàng)建一個觀察者,實現(xiàn)java.util.Observer接口
· 注冊觀察著,調(diào)用addObserver(Observer observer)
·在被觀察者改變對象內(nèi)部狀態(tài)的地方,調(diào)用setChanged()方法,然后調(diào)用notifyObservers(Object)方法,通知被觀察者
·在觀察者的update(Object)方法中,對改變做出響應(yīng)。
四、Observer模式的好處:
1.Observer模式的優(yōu)點:
·被觀察者只需要知道誰在觀察它,無需知道具體的觀察細(xì)節(jié)
·被觀察者一旦發(fā)生變化,只需要通過廣播的方式告知觀察者,至于消息如何到達(dá)則不需知道。這樣的話無疑消除了被觀察者和觀察者之間通信的硬編碼
·當(dāng)一個被觀察者同時被多個觀察著觀察時,觀察者可以只選擇自己感興趣的事件,而忽略其它的事件
·多個觀察者組合起來可以形成一個觀察鏈,如果一旦需要回滾多個操作,此時觀察鏈可以發(fā)揮作用
·觀察者可以實時對被觀察對象的變化做出響應(yīng),例如自動告警、中斷運行等
2.運用Observer模式可以
·屏蔽線程間的通信機(jī)制:例如兩個線程之間,主線程可以作為觀察者,執(zhí)行線程是被觀察者。彼此之間只知道對方存在,但不知道之間通信的細(xì)節(jié)
·消除硬編碼:如果沒有Observer模式,則只能采用回調(diào)的模式,或者在代碼中顯示地調(diào)用觀察者
·優(yōu)化異常機(jī)制:特別適合在異常發(fā)生時向頂層監(jiān)控,減少try-catch代碼量
代碼:
- public class Observable {
- private boolean changed = false;
- private Vector obs;
- //創(chuàng)建被觀察者時就創(chuàng)建一個它持有的觀察者列表,注意,這個列表是需要同步的。
- public Observable() {
- obs = new Vector();
- }
- /**
- * 添加觀察者到觀察者列表中去
- */
- public synchronized void addObserver(Observer o) {
- if (o == null)
- throw new NullPointerException();
- if (!obs.contains(o)) {
- obs.addElement(o);
- }
- }
- /**
- * 刪除一個觀察者
- */
- public synchronized void deleteObserver(Observer o) {
- obs.removeElement(o);
- }
- /**
- * 通知操作,即被觀察者發(fā)生變化,通知對應(yīng)的觀察者進(jìn)行事先設(shè)定的操作,不傳參數(shù)的通知方法
- */
- public void notifyObservers() {
- notifyObservers(null);
- }
- /**
- * 與上面的那個通知方法不同的是,這個方法接受一個參數(shù),這個參數(shù)一直傳到觀察者里,以供觀察者使用
- */
- public void notifyObservers(Object arg) {
- Object[] arrLocal;
- synchronized (this) {
- if (!changed)
- return;
- arrLocal = obs.toArray();
- clearChanged();
- }
- for (int i = arrLocal.length-1; i>=0; i--)
- ((Observer)arrLocal[i]).update(this, arg);
- }
- }
- public interface Observer {
- /**
- * This method is called whenever the observed object is changed. An
- * application calls an <tt>Observable</tt> object's
- * <code>notifyObservers</code> method to have all the object's
- * observers notified of the change.
- *
- * @param o the observable object.
- * @param arg an argument passed to the <code>notifyObservers</code>
- * method.
- */
- void update(Observable o, Object arg);
- }
- }
- public class MailObserver implements Observer{
- /**
- * 這個類取名為MailObserver,顧名思義,她是一個用來發(fā)送郵件的觀察者
- */
- public void update(Observable o, Object arg) {
- System.out.println("發(fā)送郵件的觀察者已經(jīng)被執(zhí)行");
- }
- }
- public class JMSObserver implements Observer{
- public void update(Observable o, Object arg) {
- System.out.println("發(fā)送消息給jms服務(wù)器的觀察者已經(jīng)被執(zhí)行");
- }
- }
- public class Subject extends Observable{
- /**
- * 業(yè)務(wù)方法,一旦執(zhí)行某個操作,則通知觀察者
- */
- public void doBusiness(){
- if (true) {
- super.setChanged();
- }
- notifyObservers("現(xiàn)在還沒有的參數(shù)");
- }
- public static void main(String [] args) {
- //創(chuàng)建一個被觀察者
- Subject subject = new Subject();
- //創(chuàng)建兩個觀察者
- Observer mailObserver = new MailObserver();
- Observer jmsObserver = new JMSObserver();
- //把兩個觀察者加到被觀察者列表中
- subject.addObserver(mailObserver);
- subject.addObserver(jmsObserver);
- //執(zhí)行業(yè)務(wù)操作
- subject.doBusiness();
- }
- }


