TL;DR: 我试图找到最有效的方法来动态创建功能接口的实现,该接口将调用转发到该接口的一组实例。
目标是简化接口的实现,允许客户端代码通过将处理程序(实现为功能接口)传递给适当的注册函数来为多个事件注册自己。一个例子:
/** The interface in question we want to implement with minimal effort. */
interface TrainStation {
void onTranArrived(TrainArrivedHandler handler);
void onPassengerArrived(PassengerArrivedHandler handler);
interface TrainArrivedHandler {
void apply(String track, String lineNumber);
}
interface PassengerArrivedHandler {
void apply(String track);
}
}
这可以是这种界面的一个示例。会有很多这样的接口,每个接口都有不同的事件,所以实现应该尽可能简单,没有太多重复的代码。Event
我想通过在这样的实现中引入一种供内部使用的类型,这可能最好地实现,它允许将调用转发到所有注册的处理程序:
/** Used in an implementation to implement on*() functions. */
interface Event<HANDLER> {
/** Register a handler. */
void on(HANDLER handler);
/** Returned instance calls all registered handlers. */
HANDLER getMasterHandler();
static <HANDLER> Event<HANDLER> create() {
// Magic. May need an instance of Class<HANDLER>, which is okay.
}
}
的实现TrainStation
可能如下所示:
final class TrainStationImpl implements TrainStation {
private final Event<TrainArrivedHandler> trainArrivedEvent = Event.create();
private final Event<PassengerArrivedHandler> passengerArrivedEvent = Event.create();
@Override
public void onTranArrived(TrainArrivedHandler handler) {
trainArrivedEvent.on(handler);
}
@Override
public void onPassengerArrived(PassengerArrivedHandler handler) {
passengerArrivedEvent.on(handler);
}
/** Generates some events. */
public void makeSomethingHappen() {
trainArrivedEvent.getMasterHandler().apply("34", "S12");
passengerArrivedEvent.getMasterHandler().apply("2"); // Wants to catch the S12, but is obviously too late now.
}
}
这是所需代码的可管理级别。它的大部分可以提取到一个抽象类中,因此每个接口只需要一次。当然,任何减少它的方法都是一个加号,但如果不暴露Event
实例,我看不到直接的方法。
继续使用这种方法,有趣的是接口的实现Event
。我当然可以想象用普通的旧反射来做这件事,它的表现可以接受但不是很出色。但我认为,对于 Java 1.7 或 1.8,现在应该有一种更有效和/或更直接的方式来实现Event.getMasterHandler()
使用新 API 的返回值,尤其是MethodHandle
,因为我们知道每个处理程序接口都是一个函数式接口。我该怎么做呢?