基于某些条件具有不同签名的 Java 到 return 函数的模式是什么?

What is the Java pattern to return functions with different signatures based on some condition?

我正在尝试编写一个可以从外部数据存储中查找实体的 Client class。用于查找实体的主要参数是键。问题是有时一个键只是 userId,有时它是 userIdproductId 的组合。因此,我想强制 Client API 的消费者使用特定于实体的密钥生成器。我试过下面的代码:

import java.util.function.BiFunction;
import java.util.function.Function;

public class Client {
  public Function getBuilder(SomeEnum type) {
    switch (type) {
      case TYPE_X:
        BiFunction<String, String, Entity> builder = (userId, productId) -> {
          String key = userId + "-" + productId;
          // lookup something in external data store based on the key and return the found entity
        };
        return builder;
      case TYPE_Y:
        Function<String, Entity> b = appId -> {
          String key = userId;
          // lookup something in external data store based on the key and return the found entity
        };
        return b;
    }
  }
}

代码当然不会编译,因为 return 类型不匹配。我想知道代码是否可以修复,如果不能,那么使用不同签名强制执行此类构建器的正确 Java 模式是什么。

我会如下创建一个 KeyBuilder 接口,并针对每种类型以不同方式实现它。不需要枚举:

 public interface KeyBuilder {
     String buildKey();
 }

 // things that use userId & productId:
 public class Foo implements KeyBuilder {
     // ...
     public String buildKey() { return userId + "-" + productId; }
 }

 // things that use appId {
 public class Bar implements KeyBuilder {
     // ...
     public String buildKey() { return appId; }
 }

然后,您的代码会变得更清晰并且仍然易于测试

 // before: have to build explicitly 
 lookupSomethingExternal(foo.getUserId() + "-" + foo.getProductId());
 lookupSomethingExternal(bar.getAppId());

 // after: lookupSomethingInternal expects something implementing KeyBuilder
 lookupSomethingExternal(foo);
 lookupSomethingExternal(bar);

 // after: can mock for unit-tests
 lookupSomethingExternal(() -> "testKey");