繁体   English   中英

如何降低此代码的复杂性?

[英]How can I reduce the Complexity of this code?

我正在尝试通过 DTO 创建一个搜索方法。 我的意思是用户可以通过一个字段来搜索产品。 您能否为此提出更好的方法或帮助降低此方法的复杂性?

public List<ProductDTO> search(SearchProductDTO productDTO) {
    Criteria criteria = null;
    String insensitive = "i";
    if (StringUtils.isNotBlank(productDTO.getName()))
        criteria = Criteria.where(NAME.getLabel()).regex(productDTO.getName(), insensitive);
    if (StringUtils.isNotBlank(productDTO.getDescription()))
        criteria = criteria != null ? criteria.and(DESCRIPTION.getLabel()).regex(productDTO.getDescription(), insensitive) : Criteria.where(DESCRIPTION.getLabel()).regex(productDTO.getDescription(), insensitive);
    if (productDTO.getPrice() != 0)
        criteria = criteria != null ? criteria.and(PRICE.getLabel()).is(productDTO.getPrice()) : Criteria.where(PRICE.getLabel()).is(productDTO.getPrice());
    if (StringUtils.isNotBlank(productDTO.getBrand()))
        criteria = criteria != null ? criteria.and(BRAND.getLabel()).regex(productDTO.getBrand(), insensitive) : Criteria.where(BRAND.getLabel()).regex(productDTO.getBrand(), insensitive);
    if (productDTO.getProductSize() != null)
        criteria = criteria != null ? criteria.and(SIZE.getLabel()).is(productDTO.getProductSize()) : Criteria.where(SIZE.getLabel()).is(productDTO.getProductSize());
    if (productDTO.getStockCount() != 0)
        criteria = criteria != null ? criteria.and(STOCK_COUNT.getLabel()).is(productDTO.getStockCount()) : Criteria.where(STOCK_COUNT.getLabel()).is(productDTO.getStockCount());
    if (StringUtils.isNotBlank(productDTO.getType()))
        criteria = criteria != null ? criteria.and(TYPE.getLabel()).regex(productDTO.getType(), insensitive) : Criteria.where(TYPE.getLabel()).regex(productDTO.getType(), insensitive);
    if (StringUtils.isNotBlank(productDTO.getColor()))
        criteria = criteria != null ? criteria.and(COLOR.getLabel()).regex(productDTO.getColor(), insensitive) : Criteria.where(COLOR.getLabel()).regex(productDTO.getColor(), insensitive);
    if (productDTO.getGender() != null)
        criteria = criteria != null ? criteria.and(GENDER.getLabel()).is(productDTO.getGender()) : Criteria.where(GENDER.getLabel()).is(productDTO.getGender());
    Pageable pageable = PageRequest.of(productDTO.getPage(), productDTO.getSize());
    Query query = new Query().with(pageable);
    query = criteria != null ? query.addCriteria(criteria).with(pageable) : query;
    List<Product> products = mongoTemplate.find(query, Product.class);
    return products.stream().map(productMapper::modelToDto).collect(Collectors.toList());
}

更好的做法是将空检查 + 追加 where 子句 + 将参数分配到它自己的方法中。 这样你的代码会更容易理解。

您还可以包装 Criteria 类并添加例如“optionalWhere()”,它执行空检查并仅在参数具有值时附加 where 子句。

...不幸的是,我不知道为什么 API 本身没有解决动态查询的问题,例如从 GUI 搜索...

您可以通过将标准动态收集到列表中并将此列表合并为单个“多”标准来摆脱空检查

List<Criteria> criterias = new ArrayList<>();

// collect
if (StringUtils.isNotBlank(productDTO.getName()))
    criterias.add(Criteria.where(NAME.getLabel()).regex(productDTO.getName(), insensitive));
if (StringUtils.isNotBlank(productDTO.getDescription()))
    criterias.add(Criteria.where(DESCRIPTION.getLabel()).regex(productDTO.getDescription(), insensitive));
if (productDTO.getPrice() != 0)
    criterias.add(Criteria.where(PRICE.getLabel()).is(productDTO.getPrice()));
// and so on ...

// combine
Criteria multiCriteria = new Criteria().andOperator(criterias.toArray(new Criteria[criterias.size()]));

// use
Pageable pageable = PageRequest.of(productDTO.getPage(), productDTO.getSize());
Query query = new Query().with(pageable);
query.addCriteria(multiCriteria);

暂无
暂无

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

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