Should I be exposing Stream on my interface?

前端 未结 3 1558
失恋的感觉
失恋的感觉 2021-01-06 08:39

If I am writing .NET code I would often expose IEnumerable where-ever it could possibly make sense. Maybe it was down to LINQ and the fact you could us

相关标签:
3条回答
  • 2021-01-06 08:46

    Whether or not you want to be a Stream yourself, primarily depends on whether you're truly a Stream with the corresponding powers, i.e. support parallelization (not all Streams do, but it's one of the many benefits of Streams, and it's an important one). Normally I'd rather be a Collection and let myself be Streamed by the corresponding API calls.

    The getStuff() method, returning Stream<String> from myCollection.stream() looks right to me.

    0 讨论(0)
  • 2021-01-06 08:47

    Avoid Stream where possible in interfaces.

    Streams may * be finite or infinite * be sequential or parallel * be ordered or non-ordered * need closing or not

    Neither the implementors of an interface nor the clients of the interface can know which of these characteristics should (not) apply or which they need to guard against.

    Choosing the most flexible return type in an interface just means that clients have the full burden of guarding against all possibilities. It is generally much more useful in an interface to restrict the returned datatype so that implementors know what assumptions they can rely one (for the same reason returning Collection itself is not very useful in most cases, it is more useful to return List, Set, Iterable, InputStream to indicate rights and duties of clients when consuming the data).

    And when you need to change the characteristics of the returned data, change the interface,b break your clients intentionally, so that they can update their algorithms to the changed situation.

    That's much more useful than to say: "My method returns a Stream, so now I can return an infinite stream instead of a finite one, and the client code still compiles, how wonderful!". It is not wonderful, it is a horrible source of bugs to do that. Client code should NOT continue to compile with such drastic changes, so using datatypes that are explicit about finity, parallelity, orderedness and duty to close() is a much better choice.

    Think like this: If remaining flexible was so great, then all interfaces that in Java7 return List or Set or Queue would be returning Iterable instead, to remain flexible in what datatype to actually return. But this is not what most interfaces do returning a Collection instead tells clients they can safely rely on a size() method, and returning a Set means they can safely rely on non-duplication, as an example. Being specific and restrictive in interfaces is not a sin, it is a virtue.

    0 讨论(0)
  • 2021-01-06 08:57

    You are asking the wrong question. After all, it isn’t hard to support both, e.g.

    Collection<Foo> getStuff();
    default Stream<Foo> stuff() {
        return getStuff().stream();
    }
    

    so code using your interface doesn’t need an explicit stream() call, while implementors of the interface don’t need to bother with it as well.

    As you are always exposing a Stream support whether via Collection.stream() or explicitly, the question is whether you want to expose the Collection. While it is cheap to provide a Stream for a Collection back-end it might turn out to be expensive to collect a Collection from a Stream.

    So an interface exposing both ways suggests that they are equally usable while for an implementation not using a Collection back-end one of these methods might be way more expensive than the other.

    So if you are sure that all implementations, including future ones, will always use (or have to support) a Collection it might be useful to expose it though the API as Collections support certain operations which Stream doesn’t. That’s especially true if you support modification of the underlying data via the exposed Collection.

    Otherwise, supporting Stream access only might be the better choice. This gives implementations the freedom to have other back-ends than a Collection. However, that also implies that this API does not support Java versions prior to Java 8.

    0 讨论(0)
提交回复
热议问题