2012-01-12 46 views
1

我看到有一个实用程序来创建Function<A,C>,这是Function<A,B>的组成和Function<B,C>番石榴函数组合

我有一个类似的,但有点不同的情况。

我的第一个函数是valueOfFunction,它根据我的BO类中的键返回一个枚举。

SECOND函数使用参数(即BO对象)调用Enum上的方法。

所以它不是完全A->B->C

这里的功能:

private final static class RequestConvertor implements Function<CoreData, List<Request>> { 
    private final static Function<String,RequestConvertorEnum> typeConvertor = valueOfFunction(RequestConvertorEnum.class); 

    @Override 
    public List<Request> apply(CoreData coreData) { 
     RequestConvertorEnum requestConvertorEnum = typeConvertor.apply(coreData.getType()); 
     return requestConvertorEnum.convertToRequests(coreData); 
    } 

} 

这里枚举的方法:

private final List<Request> convertToRequests(CoreData coreData) { 
     List<PropertyWrapper> properties = getProperties(coreData); 
     if (properties.size() == 0) { 
      return Collections.emptyList(); 
     } 
     Request request = new Request(coreData.getKey(), properties, new RequestMetaData(
       coreData.getFoo())); 
     return newArrayList(request); 
    } 

是否有构成这两个功能在一起更好的方式?

回答

1

我认为valueOfFunction的用法是在第一个地方不恰当的 - 你正在使用它在另一个函数(这是private static成员)立即调用apply方法。你应该用好老Enum.valueOf(String)静态方法:

private final static class RequestConvertor 
     implements Function<CoreData, List<Request>> { 
    @Override 
    public List<Request> apply(CoreData coreData) { 
     return RequestConvertorEnum.valueOf(coreData.getType()) 
       .convertToRequests(coreData); 
    } 
} 

注意当字符串并不代表任何枚举值抛出IllegalArgumentException,但你现在的代码在运行时(Enums.valueOfFunction returns null if the Enum constant does not exist)具有潜在NullPointerException,我想你知道它(如果你不是,你现在:))。

此外还有一些关于其余代码的建议。如果你不需要可变性,使用ImmutableLists而不是ArrayList(我假定你不修改结果,因为Collections.emptyList本身是不可改变的,所以如果你修改convertToRequests方法的结果,它将在运行时失败)。

private final ImmutableList<Request> convertToRequests(CoreData coreData) { // 1. 
    List<PropertyWrapper> properties = getProperties(coreData); 
    if (properties.size() == 0) { 
     return ImmutableList.of(); // 2. 
    } 
    Request request = new Request(coreData.getKey(), properties, 
      new RequestMetaData(coreData.getFoo())); 

    return ImmutableList.of(request); // 3. 
} 

几点说明:

  1. 使用ImmutableList的返回类型担保行为(immutablility)。
  2. 返回空的不可变列表,但是better than JDK's one
  3. 与2相同,但单身不变的列表在这里。

如果您需要可变性,请将ImmutableList.of替换为Lists.newArrayList并保留方法签名不变。

+0

谢谢。我知道转换为Enum可能存在的异常。字符串类型是我们从DB获得的东西,我更喜欢将它传递并仅在需要时才转换为Enum。感谢收集的意见。我认为我们可以使用不可变列表。 – 2012-01-13 10:29:23

+0

字符串 - >枚举常量将只在需要时在RequestConvertor的apply方法中完成 - 您将调用'valueOfFunction.apply'方法,而我将调用'Enum.valueOf'静态方法,而不创建第二个Function对象。 – Xaerxess 2012-01-13 10:51:24