java - 这个在 Java 8 中使用 Optionals 的例子是否正确?你会如何重写它?

标签 java java-8 java-stream monads option-type

我已经开始使用 Java 的 8 个可选项。我想分享这个方法,它是“代码味道”的例子,我想用 java 8 和 optionlas 以及函数式(声明式)风格重写它,所以我很想知道你对它的看法。让我们考虑一下这个方法:

  public boolean isTokenValid(String userAgent, Optional<String> apiKey) {
    LOGGER.info(String.format("userAgent : %s, Key ?: %s", userAgent, apiKey.isPresent()));
    if ("ALFA".equalsIgnoreCase(userAgent)){
        return (apiKey != null && apiKey.isPresent()
                && ispropertyExists(ALFA_TYPE, apiKey.get()));
    }
    else {
        return (apiKey != null && apiKey.isPresent()
                && ispropertyExists(BETA_TYPE, apiKey.get()));
    }
}

其中“ispropertyExists”返回 boolean 类型,“ALFA_TYPE”和“OMEGA_TYPE”是枚举常量。 所以下面是我重写这个方法的方式,目的是提高可读性和实践函数式思维方式。我已经添加了评论,以解释我这样做的想法和原因,如果您认为可以改进它,我很感谢您的意见和示例。

    /**
 * We should not pass Optionals as a parameters to the methods. We
 * should use Optionals only for return value when we are not sure if value will
 * be presented at the end of the calculations or not.
 */
public boolean isTokenValid(String userAgent, String apiKey) {
    LOGGER.info(String.format("userAgent : %s, Key ?: %s", userAgent, apiKey));

    /**
     * If apiKey is null then it is incorrect. And execution will stop after
     * Optional.ofNullable(apiKey), since monad will be having null value. If apiKey
     * is not null then we still want to filter out empty strings. If after filter
     * there will be no value, then execution will stop.
     * If we have some value for apiKey then it is ok and we map the monad to the
     * userAgent value to proceed the chain of calls on monad.
     */
    Optional<String> userAgentOptional = Optional.ofNullable(apiKey).filter(StringUtils::isNotBlank)
            .map(ak -> userAgent);

    /**
     * We map "userAgent" value to boolean (if it is a alfa or not). Then
     * we map that boolean to boolean value which represents security check in db
     * itself.
     */
    Optional<Boolean> isValid = userAgentOptional.map(ua -> "ALFA".equalsIgnoreCase(ua))
            .map(isAlfa -> isAlfa ? ispropertyExists(ALFA_TYPE, apiKey)
                    : ispropertyExists(BETA_TYPE, apiKey));

    /**
     * And all in all we get value from our optional boolean. If "somehow" it is
     * ended up to be empty, then we retrun "false", if it is not empty, then the
     * value will itself be returned.
     */
    return isValid.orElse(false);
}

谢谢。

最佳答案

我会将所有操作组合在一个链式语句中并返回结果,避免不必要的Optional 变量。

 return Optional.ofNullable(apiKey)
                .filter(StringUtils::isNotBlank)
                .map(ak -> userAgent)
                .map("ALFA"::equalsIgnoreCase)
                .map(isAlfa -> isAlfa ? ALFA_TYPE : BETA_TYPE)
                .map(type -> ispropertyExists(type, apiKey))
                .orElse(false);

关于java - 这个在 Java 8 中使用 Optionals 的例子是否正确?你会如何重写它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53248205/

相关文章:

java - 如何通过Java恢复MySQL转储文件?

java - 即使没有 dekker/peterson 的算法,Java 中的多线程也能工作吗?

java - 从 Java 7 更改 RequestMapping 方法或在 Java 8 中添加 Optional

java - 使用 java8 Streams 在列表中合并内部列表

java - 如何循环访问多个列表并使用 Java 8 lambda 表达式合并两个列表中的唯一值来创建另一个列表

java - 如何在运行时过滤 java 对象列表,其中我要过滤的变量事先未知?

java - httpClient 连接池管理器 validateAfterInactivity

asynchronous - 如何从异步 Http 客户端请求获取 CompletableFuture<T>?

java - Spark Java : java. lang.NoClassDefFoundError

java - 服务器套接字 : No port Forwarding