2011-06-29 186 views
4

我有一個MyObserver類,用於監聽通告程序中的更改。通告程序使用notifyObservers(Object)擴展Observable並通知它的事件。作爲參數傳遞的對象始終是同一個類的實例。問題是每個觀察者需要聽不同的事件。例如,一個觀察者需要聽取狀態改變的事件以及其他事件的所有類型的事件。我如何用觀察者模式來做到這一點?具有兩個觀察者列表的觀察者模式

謝謝。

+0

當你說實現Observable。你的意思是你實現了你自己的Observable接口還是擴展java.util.Observable? – peshkira

+0

究竟,你面臨的問題是什麼? – Bohemian

+0

我實現了java.util.Observable。 –

回答

3

如果你可以改變設計了一下:

interface MyObserver { 
    public void stateChangeEvent(); 
    public void otherEvent(); 
} 

class MyObserverAdapter implements MyObserver { 
    public void stateChangeEvent() { 
     // some default implementation or no implementation. 
    } 

    public void otherEvent() { 
     // some default implementation or no implementation. 
    } 
} 

class MyStateChangeObserver extends MyObserverAdapter { 
    public void stateChangeEvent() { 
     // implement behavior specific to this class. 
    } 
} 

class MyOtherObserver extends MyObserverAdapter { 
    public void otherEvent() { 
     // implement behavior specific to this class. 
    } 
} 

用法:

MyObserver stateObserver = new MyStateChangeObserver(); 
MyObserver otherObserver = new MyOtherObserver(); 
notifier.notifyObservers(stateObserver); 
notifier.notifyObservers(otherObserver); 
+0

不錯。沒有默認實現,所以我認爲我可以刪除MyObserverAdapter。但是,如果我刪除它,怎麼能只聽一個事件而不是全部?也許我需要適配器類。 –

+0

@David適配器可能仍然有用,因爲您只需在其他兩個類中實現所需的方法。 –

+0

我不明白你的使用例子。主類(觀察者)是否必須實現MyStateChangeObserver? –

5

使用notifyObservers(Object arg)版本並創建某種類型的「事件類型」對象。在你的觀察類中簡單地過濾傳入的事件類。

public void update(Object observable, Object arg) { 
    if ((MyEvent) arg.isEventX()) { /* do stuff */ } 
} 
+0

你能告訴我一個簡短的例子嗎? –

+0

我的意思是關於事件類的一個小例子,但是謝謝你的例子。 –

0

可以測試做可觀察類下面的狀態變化:

public void update(Observable o, Object arg) 
{ 
    if(o.hasChanged()) 
    { 
     // do something 
    } 
} 

觀察者說l任何事情都不需要這個測試。如果您只想監聽狀態更改,這可能是最簡單的方法。

5

我認爲觀察者模式的Java內置實現不適合您的情況。

實際上,只有一種可觀察類型的事件會出現時,通用觀察者模式纔可用。在觀察者設計模式中,全部觀察者得到通知總是

所以,在這種情況下,你需要定義自己的可觀察到的接口,例如延長一般觀察者模式,這種方式:

public enum EventKind { 
    EVENT_A, EVENT_B, EVENT_C; 
} 

public interface Observable { 
    public void registerObserver(EventKind eventKind); 
    public void unregisterObserver(EventKind eventKind); 
    public void notifyObservers(EventKind eventKind); 
} 

然後,你可以實現這個可觀測接口內部列表爲每種事件通知。如果您願意,您仍然可以使用Java內置的Observer界面。

這種方法具有以下優點:

  1. 您可以靈活增加更多類型的事件 而不影響 觀察員的代碼。
  2. 您可以註冊任何觀察者到任何 事件。
  3. 更新只是觀察員 是在 每個事件有效興趣
  4. 您可以避免觀察者端的「空方法」,「事件類型檢查」和其他 技巧