2014-01-08 14 views
2

當我編寫一些API時,我儘量避免引入新的接口,並且這常常使我想使用guava接口「Function」。例如,而不是做:使用guava函數接口與引入新類型

// a new interface 
interface URILookup { 
    public URI lookup(Object o); 
} 

public class Some { 
    public Some(URILookup u){//...} 
} 

我更換URILookupFunction<Object,URI>並記錄Some在構造函數中使用。

我覺得這可能以後導致無法讀取的代碼,我可以做一切功能。什麼標準,你將找到VS引入新的類型,例如「常規」界面之間的平衡?

+1

很多時候我用我自己的接口擴展'Function'兩全。我的規則很簡單:「任何功能會做還是需要特殊功能?」。 – maaartinus

回答

4

我對此使用了一個非常簡單的規則。

當您編寫應該執行某些通用操作的代碼時(例如,Guava的Iterables.transform()將某些函數應用於迭代器的某些元素;它根本不關心該函數完成或應該做什麼),則使用通用接口,如Function<F, T>

當你編寫代碼傳遞給它應該做的「功能」任何想法(比如在你的榜樣 - Some類預計其構造函數的參數應該以某種方式從對象獲得一個URI),這將是更自然地爲它創建一個獨特的界面。

這可以更正式地重新配置。如果您需要使用泛型類型的具體實例,即對於任意FT(如Iterables.transform())不是Function<F, T>,那麼您最好創建單獨的界面,如URILookup而不是使用Function<Object, URI>。否則,你應該堅持使用通用接口。

當然,在邊界情況下也有例外,例如,當代碼在精神上是通用的,但在實現意義上不是真正通用的時候(例如類似Function<T, Integer>)或需要與第三方API兼容時。那麼你的決定將取決於案件的具體細節。

順便說一句,這是真實的(在我看來)爲Java,但它不是對其他JVM語言,如Scala中,具有功能類型內置相當真實。如果語言本身支持函數,那麼您應該盡力支持這種支持。

+0

感謝您的回答。 – zedoo