gpt4 book ai didi

java - 降低函数的圈复杂度

转载 作者:太空宇宙 更新时间:2023-11-04 10:49:22 25 4
gpt4 key购买 nike

我有一个函数,它使用 JPA Criteria API 根据我传递给它的一些参数从数据库检索数据。使用对象 gridParams 传递参数,如下所示:

public List<MyObjectDTO> find(final GridParamsDTO gridParams) {

final CriteriaBuilder builder = getCriteriaBuilder();
final List<Predicate> predicates = new ArrayList<>();

final CriteriaQuery<MyObjectDTO> criteriaQuery = builder.createQuery(MyObjectDTO.class);

final Root<MyObject> from = criteriaQuery.from(MyObject.class);

Join<MyObject, AnotherObject> join = from.join(MyObject_.anotherObject, JoinType.LEFT);

if ((gridParams.getFilter() != null) && (gridParams.getFilter().length > 0)) {

for (final GridFilterDTO filter : gridParams.getFilter()) {
if ("fieldX".equals(filter.getField())) {
final List<Predicate> sqPredicates = new ArrayList<>();
Subquery<Long> sq = criteriaQuery.subquery(Long.class);
Root<ObjectX> sqFrom = sq.from(ObjectX.class);
sqPredicates
.add(builder.equal(sqFrom.get(ObjectX_.organismeIDE), filter.getFilterSingleValue()));
sq.select(sqFrom.get(ObjectX_.referentielID).get(MyObject_.objectX));
sq.where(builder.and(sqPredicates.toArray(new Predicate[sqPredicates.size()])));
predicates.add(builder.in(from.get(MyObject_.objectX)).value(sq));
}
if ("fieldA".equals(filter.getField()) || "fieldB".equals(filter.getField())) {
final GridFilterOperatorEnum gridFilterEnumValues = GridFilterOperatorEnum.values()[filter.getOperator().ordinal()];
switch (gridFilterEnumValues) {
case TEXT_CONTAINS:
predicates.add(builder.like(builder.upper(from.get(filter.getField())), "%" + filter.getFilterSingleValue().toUpperCase() + "%"));
break;
case TEXT_START_WITH:
predicates.add(builder.like(builder.upper(from.get(filter.getField())), filter.getFilterSingleValue().toUpperCase() + "%"));
break;
case TEXT_DIFFERENT:
predicates.add(builder.notEqual(from.get(filter.getField()), filter.getFilterSingleValue()));
break;
case TEXT_END_WITH:
predicates.add(builder.like(builder.upper(from.get(filter.getField())), "%" + filter.getFilterSingleValue().toUpperCase()));
break;
case TEXT_EQUALS:
predicates.add(builder.equal(builder.upper(from.get(filter.getField())), filter.getFilterSingleValue().toUpperCase()));
break;
default:
break;
}
}
if ("dateField1".equals(filter.getField()) || "dateField2".equals(filter.getField())) {
final GridFilterOperatorEnum gridFilterEnumValues = GridFilterOperatorEnum.values()[filter.getOperator().ordinal()];
switch (gridFilterEnumValues) {
case DATE_EQUALS:
predicates.add(builder.equal(from.<LocalDate> get(filter.getField()), LocalDate.parse(filter.getFilterSingleValue())));
break;
case DATE_BEFORE:
predicates.add(builder.lessThan(from.<LocalDate> get(filter.getField()), LocalDate.parse(filter.getFilterSingleValue())));
break;
case DATE_AFTER:
predicates.add(builder.greaterThan(from.<LocalDate> get(filter.getField()), LocalDate.parse(filter.getFilterSingleValue())));
break;
case DATE_BETWEEN:
predicates.add(
builder.between(from.<LocalDate> get(filter.getField()), LocalDate.parse(filter.getFilterSetValues()[0]),
LocalDate.parse(filter.getFilterSetValues()[1])));
break;
default:
break;
}
}
if ("anotherField".equals(filter.getField())) {
if (filter.getFilterSetValues().length > 0) {
predicates
.add(builder.isTrue(join.get(AnotherObject_.lib).in((Object[]) filter.getFilterSetValues())));
} else {
predicates.add(join.get(AnotherObject_.lib).isNull());
}

}
}

}

if (gridParams.hasSort()) {
List<Order> orderList = new ArrayList<>();
for (IGridSort gridSort : gridParams.getSort()) {
if (ArrayUtils.contains(new String[] { "fieldA", "dateField1", "dateField2", "fieldB" }, gridSort.getField())) {
if (gridSort.getSort().equalsIgnoreCase(GridSortDTO.ASC)) {
orderList.add(builder.asc(from.get(gridSort.getField())));
} else if (gridSort.getSort().equalsIgnoreCase(GridSortDTO.DESC)) {
orderList.add(builder.desc(from.get(gridSort.getField())));
}
}
if (gridSort.getField().equalsIgnoreCase("anotherField")) {
if (gridSort.getSort().equalsIgnoreCase(GridSortDTO.ASC)) {
orderList.add(builder.asc(join.get(AnotherObject_.lib)));
} else if (gridSort.getSort().equalsIgnoreCase(GridSortDTO.DESC)) {
orderList.add(builder.desc(join.get(AnotherObject_.lib)));
}
}
}
if (!orderList.isEmpty()) {
criteriaQuery.orderBy(orderList);
}
}

predicates.add(builder.between(builder.literal(LocalDate.now()), from.get(MyObject_.dateDebut),
from.get(MyObject_.dateFin)));

criteriaQuery.multiselect(from.get(MyObject_.objectX), from.get(MyObject_.dateDebut), from.get(MyObject_.dateFin),
from.get(MyObject_.lib), from.get(MyObject_.coleur), join,
from.get(MyObject_.refExterne));
criteriaQuery.where(builder.and(predicates.toArray(new Predicate[predicates.size()])));
criteriaQuery.distinct(true);

final TypedQuery<MyObjectDTO> typedQuery = getEntityManager().createQuery(criteriaQuery);

if (gridParams.hasStart()) {
typedQuery.setFirstResult(gridParams.getStartRow());
}
if (gridParams.hasEnd()) {
typedQuery.setMaxResults(gridParams.getEndRow() - Math.max(0, gridParams.getStartRow()));
}

return typedQuery.getResultList();
}
}

问题是 SonarQube 提示这个方法“find”的循环复杂度是 31,大于授权的 30,我做了一些研究,发现我必须重构我的函数以降低循环复杂度。

在此函数中,我必须测试 gridParams 是否定义了 4 个字段:(开始、结束、排序和过滤器),排序和过滤器是对象数组,因此我必须迭代它们。

最终我需要检查很多字段,但我不知道如何在没有大量检查的情况下完成此操作:/

我该如何解决这个问题?

最佳答案

您可能想首先查看 Refactoring Catalog 中的一些重构。 .

如果你看看你的方法,你会发现有很多部分:

  • 编译谓词列表的部分
  • 编译订单列表的部分
  • 创建查询的部分
  • 运行查询的部分

这些是使用提取方法重构重构为单独方法的良好候选者。一旦这些部分被提取到新的方法中,就可以在每种方法上重复该过程,直到您认为您已经完成了尽可能多的操作。然后,您可以查看您创建的新方法并识别那些操作相同数据的方法。他们可能希望转移到单独的类,例如查询类。

switch 语句看起来也很适合用多态性重构替换条件。

如果有疑问,请从小处开始,一次进行一个简单的重构。

关于java - 降低函数的圈复杂度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48004930/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com