嵌套callback的Java模式?

我正在寻找一个Java模式来进行非阻塞方法调用的嵌套序列。 在我的情况下,一些客户端代码需要asynchronous地调用一个服务来执行一些用例,而这个用例的每一步必须是asynchronous执行的(因为这个问题的范围之外的原因)。 想象一下,我有现有的接口,如下所示:

public interface Request {} public interface Response {} public interface Callback<R extends Response> { void onSuccess(R response); void onError(Exception e); } 

RequestResponse接口有不同的配对实现,即RequestA + ResponseA (由客户端提供), RequestB + ResponseB (由服务内部使用)等。

处理stream程如下所示:

显示嵌套回调的序列图。

在收到每个响应和发送下一个请求之间,需要进行一些额外的处理(例如根据任何以前的请求或响应中的值)。

到目前为止,我已经尝试了两种使用Java编码的方法:

  • 匿名类:由于所需的嵌套,很快变得丑陋
  • 内部类:比上面更清晰,但是对于另一个开发者来说仍然难以理解执行的stream程

有没有一些模式,使这个代码更具可读性? 例如,我是否可以将服务方法表示为一个自包含操作的列表,由依赖嵌套的框架类按顺序执行?

由于实现(不仅是接口)不能阻止,我喜欢你的列表的想法。

设置一个“操作”(也许是Future ?)的列表,为此设置应该非常清晰和可读。 然后在收到每个响应之后,应该调用下一个操作。

有一点想象力,这听起来像责任链 。 这是我想象中的一些伪代码:

 public void setup() { this.operations.add(new Operation(new RequestA(), new CallbackA())); this.operations.add(new Operation(new RequestB(), new CallbackB())); this.operations.add(new Operation(new RequestC(), new CallbackC())); this.operations.add(new Operation(new RequestD(), new CallbackD())); startNextOperation(); } private void startNextOperation() { if ( this.operations.isEmpty() ) { reportAllOperationsComplete(); } Operation op = this.operations.remove(0); op.request.go( op.callback ); } private class CallbackA implements Callback<Boolean> { public void onSuccess(Boolean response) { // store response? etc? startNextOperation(); } } ... 

在我看来,模拟这类问题的最自然的方式是Future<V>

因此,不要使用callback,而只需返回一个“thunk”:一个Future<Response> ,表示未来某个时候可用的响应。

然后,您可以将后续步骤build模为Future<ResponseB> step2(Future<ResponseA>) ,或使用Guava的ListenableFuture<V> 。 然后,您可以使用Futures.transform()或其重载之一以自然的方式链接您的函数,但仍保留asynchronous性质。

如果以这种方式使用, Future<V>行为就像一个monad(事实上,我认为它可能是一个,虽然我不能确定我的头顶),所以整个过程有点像IO在Haskell中通过IO monad执行。

你可以使用演员计算模型。 在你的情况下,客户端,服务和callback[BD]都可以表示为angular色。

java有很多演员库。 然而,他们中的大多数都是重量级的,所以我写了一个紧凑的,可扩展的: df4j 。 它将演员模型视为更一般的数据stream计算模型的具体情况,并因此允许用户创build新types的演员,以最佳地满足用户的需求。

我不知道如果我正确地得到你的问题。 如果你想调用一个服务,并且它的完成结果需要传递给其他可以继续使用结果处理的对象。 你可以看看使用Composite和Observer来实现这一点。