3

实现以各种指定方式组合同一接口的某些实例的接口的最佳方法是什么?我需要为多个接口执行此操作,并且我希望最大限度地减少样板代码并仍然实现良好的效率,因为我需要它用于关键生产系统。

这是问题的草图。

抽象地说,我有一个通用组合器类,它接受实例并指定各种组合器:

class Combiner<I> {
   I[] instances;

   <T> T combineSomeWay(InstanceMethod<I,T> method) {
     // ... method.call(instances[i]) ... combined in some way ...
   }

   // more combinators
}

现在,假设我想在许多其他接口中实现以下接口:

Interface Foo {
  String bar(int baz);
}

我想结束这样的代码:

class FooCombiner implements Foo {
  Combiner<Foo> combiner;

  @Override 
  public String bar(final int baz) {
    return combiner.combineSomeWay(new InstanceMethod<Foo, String> {
      @Override public call(Foo instance) { return instance.bar(baz); } 
    });
  }
}

现在,如果接口有很多方法,这很快就会变得冗长而曲折。我知道我可以使用 Java 反射 API 中的动态代理来实现这样的接口,但是通过反射访问方法要慢一百倍。那么在这种情况下,样板和反射的替代方案是什么?

4

2 回答 2

2

我会建议使用动态代理——这些天它真的比常规方法调用慢得多吗?我听说反射在幕后做了相当多的魔法来加速重复的方法调用。(如果它慢 100 倍,你确定你会注意到吗?好的,只要重新阅读你的问题 - 你会注意到的!)

否则,您基本上可以在您的问题中找到解决方案:使用 Command 对象将每个方法包装在您的界面中。然后,您可以将接口集合中的每个实例传递给命令对象进行处理。

当然,如果您有勇气和冒险精神,您可以使用 cglib、javassist 或其他动态字节码生成器生成命令对象的实现,以及使用动态类生成的组合器接口的实现。那将避免样板。

您也可能在方面取得了一些成功,特别是在编译时或加载时编织方面的方面,因此您避免了反射开销。对不起,我不能提供细节。

于 2010-05-22T00:41:57.243 回答
1

您可以反转您的组合器:

@Override
public String bar(int baz)
{
    //for (Foo f:combiner.combineSomeWay())// returns Iterator<Foo>
    for (Foo f:combiner) //combiner must implement Iterable<Foo> or Iterator<Foo>
    {
        // In case of several ways to combine
        // add() method should call some temp object
        // in combiner created (or installed) by 
        // combineSomeWay.
        // The best temp object to use is Iterator
        // returned by combiner.combineSomeWay();
        combiner.add(f.bar(baz));// or addResult, or addCallResult
    }
    // clear (or uninstall) temp object and result
    // thats why get* method 
    // name here is bad.
    return combiner.done(); 
}

不是单行但更容易理解。但是,如果您的方法抛出异常,那将更加复杂。您将需要 try/catch 块和addException方法。

于 2010-05-22T06:22:29.910 回答