最优雅的解决方案来链接java中的异步调用?

时间:2012-04-03 07:30:56

标签: java design-patterns asynchronous

我目前正在开发Android应用程序的表示层。

我正在使用的api看起来像这样:

public interface errorInterface{
    public void onError(String reason);
}

public interface if1 extends errorInterface{
    public void dataReceived1(Data data);
}
public interface if2 extends errorInterface{
    public void dataReceived2(Data data);
}   

public void fetchData1(if1 receiver) {}
public void fetchData2(if2 receiver) {}

那是;获取数据,你提供的接收器将在未来的某个时间收到操作的结果。

当你需要一次只调用一个方法时,这非常有效,但现在我已经达到了需要一次调用10多个这样的方法的时候,他们需要一次执行一个。< / p>

如何以灵活优雅的方式解决这个问题?

谢谢!

2 个答案:

答案 0 :(得分:7)

让我确保理解..您有一系列接口if1if2 .. ifn,您希望他们都能够处理收到的数据。< / p>

首先,如果if1if2等与您的两种基本方法完全相同,最好是public void dataReceived(Data d)public void onError(String reason)。有了它,您只需将ListCollection个接收者传递给fetchData,它就可以遍历该集合并在每个集合上调用dataReceived(d)

如果由于某种原因,这是不可行的,我会尝试使用适配器将它们引入fetchData的类似界面。例如:

public interface DataReceiver extends ErrorInterface {
  public void dataReceived(Data d); 
  //or just scrap the ErrorInterface all together and make these into 1 interface
}

public class AbstractIFAdapter<T extends ErrorInterface> implements DataReceiver {
  private T target;
  public AbstractIFAdapter(T target) { this.target = target);
  public void onError(String reason) { target.onError(reason); }
  protected T getTarget() { return target; }
}

public class IF1Adapter extends AbstractIFAdapter<IF1> {
  public IF1Adapter(IF1 target) { super(target); }
  public dataReceived(Data d) { getTarget().dataReceived1(d); }
}

public class IF2Adapter extends AbstractIFAdapter<IF2> {
  public IF2Adapter(IF2 target) { super(target); }
  public dataReceived(Data d) { getTarget().dataReceived2(d); }
}

现在有了这个,我们可以这样做:

List<DataReceiver> dataReceivers = new ArrayList<DataReceiver>();
dataReceivers.add(new IF1Adapter(someIf1Implementation));
dataReceivers.add(new IF2Adapter(someIf2Implementation));
fetchData(dataReceivers);

public void fetchData(Collection<DataReceiver> receivers) {

  try {
    Data d = getSomeData();
    for (DataReceiver dr : receivers) {
      dr.dataReceived(d);
    }
  }
  catch (Exception e) {
    for (DataReceiver dr : receivers) {
      dr.onError(e.getMessage());
    } 
  }
}

还有其他一些模式可能适用,具体取决于您的确切需求,例如访问者或可能的责任链类型模式,您将接收器链接在链表类型构造中,并且每个模式在递归中调用下一个构造 - 这将是很好的,因为fetchData不需要知道它正在获取一个集合,它只是引用链中的顶部适配器。因此,AbstractIFAdapter会引用另一个AbstractIFAdapter,我们称之为next,如果引用不为null,则会在其自己next.dataReceived(d)中调用dataReceived 1}}方法。与ServletFilter类似的想法,其中每个过滤器获取ServletRequest,然后调用chain.doFilter(request,response)

答案 1 :(得分:1)

您可以使用Google番石榴图书馆,请参阅this answer