2012-01-12 42 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