![](/img/trans.png)
[英]I can't unit test my class without exposing private fields — is there something wrong with my design?
[英]Should I be exposing Stream<T> on my interface?
如果我正在編寫.NET代碼,我會經常公開IEnumerable<T>
- 它可能有意義。 也許這取決於LINQ以及你可以使用foreach的事實,但是做到這一點感覺“正確”。
private List<String> _myList;
public IEnumerable<String> MyList
{
get { return _myList; }
}
現在我正在編寫Java 8代碼,我正在討論是否應該以可能的方式暴露Stream<T>
? 也許是因為我必須調用Collection.stream()
,感覺就像是“正在工作”,但感覺不對?
private Collection<String> myCollection;
public Stream<String> getStuff() {
return myCollection.stream();
}
Stream<T>
意味着以與IEnumerable<T>
可能相同的方式在接口上公開?
你問的是錯誤的問題。 畢竟,支持兩者並不困難,例如
Collection<Foo> getStuff();
default Stream<Foo> stuff() {
return getStuff().stream();
}
所以使用你的接口的代碼不需要顯式的stream()
調用,而interface
實現者也不需要打擾它。
由於您始終通過Collection.stream()
或顯式地公開Stream
支持,因此問題是您是否要公開Collection
。 雖然為Collection
后端提供Stream
很便宜,但從Stream
收集Collection
可能會很昂貴。
因此,暴露兩種方式的接口表明它們同樣可用,而對於不使用Collection
后端的實現,這些方法中的一種可能比另一種方法更昂貴。
因此,如果您確定所有實現(包括將來的實現)將始終使用(或必須支持) Collection
,那么通過API公開它可能是有用的,因為Collection
支持Stream
不具備的某些操作。 如果您支持通過公開的Collection
修改基礎數據,則尤其如此。
否則,僅支持Stream
訪問可能是更好的選擇。 這使得實現可以自由地擁有其他后端而不是Collection
。 但是,這也意味着此API不支持Java 8之前的Java版本。
你是否想成為一個Stream
自己,主要取決於你是否真的是一個具有相應權力的Stream
,即支持並行化(並非所有Stream
都可以,但它是Stream
的許多好處之一,它是一個重要的一個)。 通常情況下,我寧願成為一個Collection
,讓自己通過相應的API調用進行Stream
。
從myCollection.stream()
返回Stream<String>
的getStuff()
方法對我來說是正確的。
盡可能避免接口中的Stream。
流可以是有限的或無限的*是順序的或並行的*有序的或無序的*需要關閉或不關閉
接口的實現者和接口的客戶端都不知道應該(不)應用哪些特性或者需要防范哪些特性。
在界面中選擇最靈活的返回類型只意味着客戶有充分的責任來防范所有可能性。 在接口中通常更有用的是限制返回的數據類型,以便實現者知道它們可以依賴哪些假設(出於同樣的原因,返回Collection
本身在大多數情況下不是很有用,返回List, Set, Iterable, InputStream
更有用List, Set, Iterable, InputStream
用於指示客戶在使用數據時的權限和職責)。
當您需要更改返回數據的特征時,請更改界面,b有意破壞您的客戶端,以便他們可以根據更改的情況更新其算法。
這比說:“我的方法返回一個Stream,所以現在我可以返回一個無限的流而不是一個有限的流,而且客戶端代碼仍然編譯,這太棒了!”。 這不是很好,它是一個可怕的錯誤來源。 客戶端代碼不應繼續如此激烈的改動就可以編譯,所以使用是明確有關的有限性,並行性,orderedness和義務數據類型close()
是一個更好的選擇。
這樣想:如果保持靈活性如此之大,那么Java7中返回List
或Set
或Queue
所有接口都將返回Iterable
,以保持靈活的實際返回的數據類型。 但這並不是大多數接口返回集合而是告訴客戶端他們可以安全地依賴size()方法,並返回Set意味着他們可以安全地依賴非重復,作為一個例子。 在界面中具體和限制不是罪,它是一種美德。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.