首页 > 解决方案 > 可选 vs 异常,控制器 vs 服务

问题描述

我有 JAVA 设计注意事项:我在选择之间苦苦挣扎:

  1. 服务返回可选值和控制器处理不存在的情况
  2. 服务直接处理不存在的情况,如果存在则返回真实对象,如果不存在则抛出异常

是否有好的做法可以帮助我在这两种方法之间进行选择?

例如。 选项 1 控制器:

public ResponseEntity<Product> findProductById(@PathVariable Long productId) {
        return this.productService.getProductById(productId).map(
                p -> ResponseEntity.ok(p)
        ).orElseThrow(() -> new ResourceNotFoundException(ResourceType.PRODUCT, "Id", productId.toString()));
    }

服务:

    public Optional<Product> getProductById(Long id) {
        return productRepository.findById(id).map(
                product -> someLogic(product)
        );
    }

选项 2: 控制器

    public ResponseEntity<Product> findProductById(@PathVariable Long productId) {
        return ResponseEntity.ok(productService.getProductById(productId));
    }

服务

    public Product getProductById(Long id) {
        return productRepository.findById(id).map(
                product -> lazyLoadProduct(product)
        ).orElseThrow(() -> new ResourceNotFoundException(ResourceType.PRODUCT, "Id", id.toString()));;
    }

对于这两种方法,我都有一个 ControllerAdvice,它最终会将此异常转换为相应的最终用户友好消息。所以他们都“工作相同”

标签: javadesign-patternsservicecontrolleroptional

解决方案


仅当出现需要与核心业务逻辑分开处理的意外事件或情况时,才应抛出异常。在搜索资源时,未找到该资源的事件是预期结果,因此并非例外。

因此,我认为您不应该使用两种方法,而是对控制器进行编码,以便能够处理“未找到”响应的返回值。(这是一个空列表、特殊对象类型,还是仅仅null取决于您的实现最容易支持的类型。)


推荐阅读