如何使用spring webflux在功能性反应Java中编写具有多个if else的复杂代码

Sri*_*ivi 6 java spring functional-programming reactive spring-webflux

我是 RXjava 函数式编程的新手。我正在编写一个具有多种条件的 post 端点:

  1. 当发布端点被产品击中时
  2. 如果登录用户的购物车在 DB 中不存在,则创建一个新购物车
  3. 如果购物车已存在于沙发底座中,则提取该记录并检查产品 JSON 是否给定的 productid 已存在于产品 JSON 中。
  4. 如果它在产品 JSON 中不可用,则必须创建新产品
  5. 应使用新创建的 productId 更新购物车
  6. 如果它存在于产品 JSON 中,则获取产品记录并验证数量。
  7. 如果数量相同,则什么都不做
  8. 否则,更新记录。

我面临着在函数式编程中编写这些 if else 条件的挑战。尝试过switchifEmpty但无法在其中编写代码。

这是一个示例代码。

public Mono<Product> createProduct(final Tuple2<String, productdto> tuple2) {
    final Product productdto = tuple2.getT2();
    return Mono.just(tuple2.getT1())
        .map(cartRepository::findById)
        .defaultIfEmpty(cartRepository.save(
            cart.builder()
                .id(tuple2.getT1())
                .build()))
        .flatMap(cartres -> cartres)
        .flatMap(cartres -> {
             final Product product = Product.builder()
                 .id(1234)
                 .productId(productDTO.getProductId())
                 .productName(productDTO.getProductName())
                 .build();
             return productRepository.save(product)
                 .map(saveCart -> cart.builder()
                     .id(cartres.getId()).build())
                 .flatMap(cartRepository::save);
        });
    }).then(Mono.just(productDto));
}
Run Code Online (Sandbox Code Playgroud)

Eru*_*aro 1

我知道有一个复杂的 if-else 逻辑,您必须使用 Spring WebFlux 调用的反应链来实现.map().flatMap()或者defaultIfEmpty()反应链来实现。

这些反应式运算符并不总是能取代复杂的 if-else 逻辑。

实施 if-else-决策必须在您.map().flatMap()

在您的情况下,您可以java.util.Function<>为每个步骤实现一个或一个简单的方法 1..8

下面是第一个示例,该示例具有通过从存储库加载或创建新购物车来为您提供购物车的功能。

此外,它还展示了如何使用zipWith()运算符向反应链添加更多数据。

在这里,检查数据库中产品是否存在,并将结果作为布尔值传递给下游。

基于此布尔值,您可以使用 if-else-语句返回现有产品或创建新产品。


    public Mono<Product> createProduct(final Tuple2<String, Product> tuple2) {
        final Product productDTO = tuple2.getT2();
        return Mono.just(tuple2.getT1())
                //   .map(cartRepository::findById)
                //           .defaultIfEmpty(cartRepository.save(
                //               cart.builder()
                //                   .id(tuple2.getT1())
                //                   .build()))
                .flatMap(provideCart(tuple2)) // see implemented method further below

                .zipWith(productRepository.existsById(productDTO.getId()))
                .flatMap(maybeCreateProduct(productDTO)); // see implemented method further below
    }

    private Function<String, Mono<Cart>> provideCart(final Tuple2<String, Product> tuple2) {
        return id -> cartRepository.findById(id)
                .switchIfEmpty(cartRepository.save(
                        Cart.builder()
                                .id(tuple2.getT1())
                                .build()));
    }

    private Function<Tuple2<Cart, Boolean>, Mono<Product>> maybeCreateProduct(Product productDTO) {
        return cartresAndProductExists -> {
            Cart cart = cartresAndProductExists.getT1();
            Boolean productExists = cartresAndProductExists.getT2();
            if (productExists) {
                return productRepository.findById(productDTO.getProductId())
            } else {
                return productRepository.save(Product.builder()
                        .id("1234")
                        .productId(productDTO.getProductId())
                        .productName(productDTO.getProductName())
                        .build());
            }
        };
    }

Run Code Online (Sandbox Code Playgroud)

人们必须小心保持代码的可读性并避免无休止的反应步骤链。

将复杂的步骤提取到单独的方法中,甚至可能首先重新考虑该过程,以得出更简单和简化的解决方案