2013-03-06 47 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来跟踪多个侦听器,这些侦听器基于它们接受的参数作为参数。