简体   繁体   English

使用不可为空值启动可选调用链的优缺点

[英]Pros and cons of starting an Optional calls chain with a non-nullable

I had a discussion with my colleague about whether you should start an Optional chain of calls from the first nullable value or from the variable at hand, and we couldn't agree on what is the way to go.我与我的同事讨论了您是否应该从第一个可空值或从手头的变量开始一个Optional的调用链,我们无法就 go 的方式达成一致。

So, to be explicit in my question, what are the pros and cons of the two following snippets?那么,在我的问题中明确地说,以下两个片段的优缺点是什么? Is there an agreement in the community as to which is better?社区中是否有关于哪个更好的协议?

    public String findAuthorName(Book book) {
        return Optional.of(book)
                .map(Book::getAuthorId)
                .flatMap(repository::findById)
                .map(Author::getName)
                .orElse("Hello world!");
    }

or或者

    public String findAuthorName(Book book) {
        return Optional.ofNullable(repository.findById(book.getAuthorId()))
                .map(Author::getName)
                .orElse("Hello world!");
    }

There are no advantages of the first approach.第一种方法没有任何优点。 Optional should be used for objects which may be not present, but here: Optional 应该用于可能不存在的对象,但在这里:

public String findAuthorName(Book book) {
    return Optional.of(book)
                   .map(Book::getAuthorId)

you are using Optional on Book object which looks like not null, only to invoke the getter method.您在 Book object 上使用 Optional 看起来不像 null,只是为了调用 getter 方法。 book.getAuthorId()) is sufficient in this case. book.getAuthorId())在这种情况下就足够了。

The second approach clearly tells us where to expect non-present values and what we would like to do with them.第二种方法清楚地告诉我们在哪里期望非当前值以及我们想用它们做什么。

I do believe the second code snippet actually looks like (you are doing .flatMap(repository::findById) in the first one, that means repository#findById() returns optional):我确实相信第二个代码片段实际上看起来像(您在第一个中执行.flatMap(repository::findById) ,这意味着repository#findById()返回可选):

    public String findAuthorName(Book book) {
        return repository.findById(book.getAuthorId())
                .map(Author::getName)
                .orElse("Hello world!");
    }

and those code snippets behave differently: if Book#getAuthorId() returns null the first one will return "Hello world " whilst the second one may fail (depends on the implementation of repository ), so, the first one looks safer, however both those patters have a very limited usage, the main problem is there are three possible situations:并且这些代码片段的行为不同:如果Book#getAuthorId()返回 null 第一个将返回“Hello world”,而第二个可能会失败(取决于repository的实现),所以,第一个看起来更安全,但是这两个patters 的用法非常有限,主要的问题是有三种可能的情况:

  • Book#getAuthorId() is null Book#getAuthorId()是 null
  • repository.findById(book.getAuthorId()) returns Optional#empty() - there is no author in repository repository.findById(book.getAuthorId())返回Optional#empty() - 存储库中没有作者
  • Author#getName() is null Author#getName()是 null

and for all those cases the result will be Hello world - that might be acceptable when we are returning data to end-user, but there is no place for such patters in business logic.对于所有这些情况,结果将是Hello world - 当我们将数据返回给最终用户时这可能是可以接受的,但在业务逻辑中没有此类模式的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM