替代try/catch!使用Vavr库实现可组合的、函数式的错误异常处理 - Alexandre


Vavr(以前称为Javaslang)是Java 8+的对象功能库,旨在减少我们需要编写的代码量并提高代码质量。网址:www.vavr.io/
它提供了持久的集合,用于错误处理的功能抽象,并发编程,模式匹配(在最新版本中已弃用,以支持Java新的模式匹配功能)等等。
它是在values的基础上建立的,灵感来自Rich Hickey(Clojure和Datomic)的The Value of Values,因此,Vavr让我们利用values优点,将错误和异常转换未values值。
这些值具有一些函数性操作,例如map,flatMap,过滤器,fold等,这有助于我们实现流利且可读的代码。
 
假设您需要假设地处理一些用户帐户和保存在数据库中的帖子:

public User processUser(Long userId) {
    User user = repository.findById(userId);
    if (null != user) {
        try {
            processUserAccounts(user);
            return processUserPosts(user);
        } catch (ExceptionA ea) {
            log.error(ea.getMessage());
            throw new BusinessException(ea);
        } catch (ExceptionB eb) {
            log.error(eb.getMessage());
            throw new BusinessException(eb);
        }
    } else {
        throws new BusinessException("user doesn't exists");
    }
}

上面代码是是丑陋的。但是,让我们看看如何使用Vavr库的Either语法:

Function<Long, Either<Error, User>> processUser = 
    userId -> getUserFromDB(userId) // returns either Left(Error) or Right(User)
                .map(this::processUserAccounts)
                .map(this::processUserPosts);

Function<User, Either<Error, User>> getUserFromDB =
    userId -> repository
                .getUser(userId)
// repository returns vavr's Option<User>
                .toEither(new Error(
"user doesn't exists"));

Function<User, Either<Error, User>> processUserAccounts = user -> {...}
Function<User, Either<Error, User>> processUserPosts = user -> {...}

这些例子很简单。每个功能都由我们实现。这样我们可以摆脱异常并返回Eithers。
更多了解点击标题