2013-03-06 48 views
1

什麼應該是最好的Java接口或類似的模式,可以用作通用回調機制Java中的通用回調

例如它可以像

public interface GenericCallback 
{ 
    public String getID(); 
    public void callback(Object notification); 
    // or public void callback(String id, Object notification); 
} 

將需要的重寫hashCode()法案件的ID,這樣被叫識別來電者。

像上面這樣的模式對於需要報告它們從一個條件產生的類(例如,處理結束)的對象是很有用的。

在這種情況下,「父」類將使用這些GenericCallback對象的getID()方法,使他們的軌道在一個Map<String, GenericCallable>並添加或根據收到的通知移除它們。

另外,這樣一個界面應該如何命名呢?

很多人似乎更喜歡Java Observer pattern,但定義的Observable class並不方便,因爲它不是一個規避單一繼承的接口,它具有比以上簡單場景中實際需要的功能更多的功能。

+4

呃,怎麼樣'Observer' http://docs.oracle.com/javase/7/docs/api/java/util/Observer .html和'Observable' http://docs.oracle.com/javase/7/docs/api/java/util/Observable.html – 2013-03-07 00:00:50

+0

「對於覆蓋hashCode()方法的情況需要該ID,以便被調用者識別來電者。「我沒有看到這部分 – newacct 2013-03-07 00:41:18

+0

如果你有一個帶有hashCode()方法的「observable」對象,該方法根據對象狀態改變其返回值,並且跟蹤HashMap中的所有可觀察對象(例如,能夠在所有這些對象完成執行時斷言),那麼你無法匹配任何跟蹤的可觀察對象。 – PNS 2013-03-07 00:52:13

回答

4

我推薦使用觀察者模式因爲觀察者模式是解耦中的黃金標準 - 彼此依賴的對象的分離。

但我建議你使用java.util.Observable中的類避免,如果你正在尋找一個通用的回調機制。因爲Observable有兩個弱點:它不是一個接口,並且迫使你使用Object來表示事件。

您可以定義自己的事件監聽器是這樣的:

public class MyEvent extends EventObject { 
    public MyEvent(Object source) { 
     super(source); 
    } 
} 

public interface MyEventListener { 
    void handleEvent(EventObject event); 
} 

public class MyEventSource { 
    private final List<MyEventListener> listeners; 
    public MyEventSource() { 
     listeners = new CopyOnWriteArrayList<MyEventListener>(); 
    } 
    public void addMyEventListener(MyEventListener listener) { 
     listeners.add(listener); 
    } 
    public void removeMyEventListener(MyEventListener listener) { 
     listeners.remove(listener); 
    } 
    void fireEvent() { 
     MyEvent event = new MyEvent(this); 
     for (MyEventListener listener : listeners) { 
      listener.handleEvent(event); 
     } 
    } 
} 
+0

我第二次談到Observable,並且創建一個更簡單的類作爲接口(一個接近的提示,例如http://stackoverflow.com/questions/11404034/java-interface-observable)也會呈現Java觀察者界面不可用,因爲這也取決於Observable。 – PNS 2013-03-07 01:33:19

+0

在嘗試執行回調方法之前,我會先製作一個「偵聽器」的副本。 – 2013-03-07 01:40:07

+0

甚至比每次複製都要好,使用CopyOnWriteArayList來保存監聽器。 – user949300 2013-03-07 04:22:49

1

看起來像要實現觀察者模式。在this url中是Java的觀察者模式的完整實現。在你的情況下,觀察者將是回調。

另外如果你需要實現更復雜的事情,你最終會做一個事件/通知模式。看看這個其他模式here

謝謝, @leo。

+0

Observer模式的問題在於Observable定義是一個類,所以由於單一繼承,所有已經繼承另一個類的類都不能被觀察到。 – PNS 2013-03-07 00:53:35

15

我會基於傳遞的對象的類型來泛化回調。這對偵聽不同類別事件的EventListeners特別有用。例如

public interface Callback<T> { 
    public void callback(T t); 
} 

可能能夠使用類型T作爲一個地圖的關鍵。當然,如果您想區分採用相同參數的兩個回調(如String),那麼您需要類似getID()的東西。

Here my old blog about using this for Event Listeners接口Events.Listener對應於上面的Callback<T>。而Broadcasters使用Map來跟蹤多個偵聽器,這些偵聽器基於它們接受的參數作爲參數。