【问题标题】:Generic callback in JavaJava中的通用回调
【发布时间】:2013-03-06 23:58:55
【问题描述】:

最好的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 并不方便,因为它不是规避单一继承的接口,而且它具有比上述简单场景实际需要的更多功能。

【问题讨论】:

  • “在覆盖 hashCode() 方法的情况下需要 ID,以便被调用者识别调用者。”我不明白这部分
  • 如果您有一个带有 hashCode() 方法的“可观察”对象,该方法根据对象状态更改其返回值,并且您跟踪 HashMap 中的所有可观察对象(例如,能够在所有这些对象完成执行时断言),那么您将无法匹配任何跟踪的 observable。
  • 最好使用特定的、有意义的类型,而不是一般的、无意义的类型。

标签: java generics callback


【解决方案1】:

我会根据传递的 Object 类型对回调进行通用化。这对于侦听不同类别事件的 EventListener 尤其有用。例如

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

可能能够使用类型 T 作为 Map 中的键。当然,如果你想区分两个接受相同参数的回调,比如字符串,那么你需要像 getID() 这样的东西。

Here my old blog about using this for Event Listeners接口Events.Listener对应上面的Callback&lt;T&gt;。而Broadcasters 使用 Map 来根据多个侦听器接受的类作为参数来跟踪它们。

【讨论】:

  • 是否可以应用带有结果的通用回调以及某些带有 void 类型的情况?
【解决方案2】:

我建议使用观察者模式,因为观察者模式是解耦的黄金标准——分离相互依赖的对象。

但如果您正在寻找通用回调机制,我建议避免使用 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);
        }
    }
}

【讨论】:

  • 我支持你所说的 Observable 并创建该类的更简单版本作为接口(一个接近的建议,例如,stackoverflow.com/questions/11404034/java-interface-observable)也会使 Java Observer 接口不可用,因为这取决于在 Observable 上也是如此。
  • 在尝试执行回调方法之前,我会复制listeners
  • 甚至比每次都复制更好,使用 CopyOnWriteArayList 来保存侦听器。
【解决方案3】:

看起来你想实现观察者模式。 this url 是 Java 中观察者模式的完整实现。在您的情况下,观察者将是回调。

此外,如果您需要实现更复杂的东西,您最终会使用事件/通知模式。看看这个其他模式here

谢谢, @leo。

【讨论】:

  • Observer 模式的问题在于 Observable 定义是一个类,因此由于单继承,所有已经继承另一个类的类都不能成为 observable。
猜你喜欢
  • 2013-02-13
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-02
  • 1970-01-01
  • 2019-04-15
  • 2013-07-19
相关资源
最近更新 更多