干净的代码 - 使用具有特定规则的一个或多个过滤器搜索端点:如何避免多个 "ifs"?
Clean code - Search endpoint with one or more filters with specific rules: How to avoid multiple "ifs"?
如果您开发的搜索端点可以有一个或多个过滤器,并且有组合这些过滤器的特定规则,如何避免使用多个“ifs”?
private void addCriteria(ProductFilter filter, Query query) {
//user does not fill anything, throws exception
if (ObjectUtils.isEmpty(filter.getIds()) && !validateComboFilters(filter)) {
throw new RequiredFilterException();
}
//user does not fill id filter but fills other filters
if (ObjectUtils.isEmpty(filter.getIds()) && validateComboFilters(filter)) {
query.addCriteria(Criteria.where(Constants.CREATED_AT)
.gte(filter.getFromDate())
.lte(filter.getToDate()));
query.addCriteria(Criteria.where(Constants.STATUS).in(filter.getStatus()));
}
//user fills id filter and one or more other filters
if (ObjectUtils.isNotEmpty(filter.getIds())) {
query.addCriteria(Criteria.where(Constants.ID)
.is(filter.getIds()));
if (filter.filterByRangeDate()) {
query.addCriteria(Criteria.where(Constants.CREATED_AT)
.gte(filter.getFromDate())
.lte(filter.getToDate()));
}
if (filter.filterByStatus()) {
query.addCriteria(Criteria.where(Constants.STATUS).in(filter.getStatus()));
}
}
}
它可能看起来像这样。我没有检查编译,但我认为一般方法或多或少是正确的。
private static final BiFunction<ProductFilter, Query, Boolean> ADD_CRITERIA_IDS = (filter, query) -> {
boolean res = ObjectUtils.isNotEmpty(filter.getIds());
if (res)
query.addCriteria(Criteria.where(Constants.ID).is(filter.getIds()));
return res;
};
private static final BiFunction<ProductFilter, Query, Boolean> ADD_CRITERIA_STATUS = (filter, query) -> {
boolean res = filter.filterByStatus();
if (res)
query.addCriteria(Criteria.where(Constants.STATUS).in(filter.getStatus()));
return res;
};
private static final BiFunction<ProductFilter, Query, Boolean> ADD_CRITERIA_DATE_RANGE = (filter, query) -> {
boolean res = filter.filterByRangeDate();
if (res)
query.addCriteria(Criteria.where(Constants.CREATED_AT)
.gte(filter.getFromDate())
.lte(filter.getToDate()));
return res;
};
private void addCriteria(ProductFilter filter, Query query) {
boolean added = ADD_CRITERIA_IDS.apply(filter, query);
added |= ADD_CRITERIA_STATUS.apply(filter, query);
added |= ADD_CRITERIA_DATE_RANGE.apply(filter, query);
if (!added)
throw new RequiredFilterException();
}
如果您开发的搜索端点可以有一个或多个过滤器,并且有组合这些过滤器的特定规则,如何避免使用多个“ifs”?
private void addCriteria(ProductFilter filter, Query query) {
//user does not fill anything, throws exception
if (ObjectUtils.isEmpty(filter.getIds()) && !validateComboFilters(filter)) {
throw new RequiredFilterException();
}
//user does not fill id filter but fills other filters
if (ObjectUtils.isEmpty(filter.getIds()) && validateComboFilters(filter)) {
query.addCriteria(Criteria.where(Constants.CREATED_AT)
.gte(filter.getFromDate())
.lte(filter.getToDate()));
query.addCriteria(Criteria.where(Constants.STATUS).in(filter.getStatus()));
}
//user fills id filter and one or more other filters
if (ObjectUtils.isNotEmpty(filter.getIds())) {
query.addCriteria(Criteria.where(Constants.ID)
.is(filter.getIds()));
if (filter.filterByRangeDate()) {
query.addCriteria(Criteria.where(Constants.CREATED_AT)
.gte(filter.getFromDate())
.lte(filter.getToDate()));
}
if (filter.filterByStatus()) {
query.addCriteria(Criteria.where(Constants.STATUS).in(filter.getStatus()));
}
}
}
它可能看起来像这样。我没有检查编译,但我认为一般方法或多或少是正确的。
private static final BiFunction<ProductFilter, Query, Boolean> ADD_CRITERIA_IDS = (filter, query) -> {
boolean res = ObjectUtils.isNotEmpty(filter.getIds());
if (res)
query.addCriteria(Criteria.where(Constants.ID).is(filter.getIds()));
return res;
};
private static final BiFunction<ProductFilter, Query, Boolean> ADD_CRITERIA_STATUS = (filter, query) -> {
boolean res = filter.filterByStatus();
if (res)
query.addCriteria(Criteria.where(Constants.STATUS).in(filter.getStatus()));
return res;
};
private static final BiFunction<ProductFilter, Query, Boolean> ADD_CRITERIA_DATE_RANGE = (filter, query) -> {
boolean res = filter.filterByRangeDate();
if (res)
query.addCriteria(Criteria.where(Constants.CREATED_AT)
.gte(filter.getFromDate())
.lte(filter.getToDate()));
return res;
};
private void addCriteria(ProductFilter filter, Query query) {
boolean added = ADD_CRITERIA_IDS.apply(filter, query);
added |= ADD_CRITERIA_STATUS.apply(filter, query);
added |= ADD_CRITERIA_DATE_RANGE.apply(filter, query);
if (!added)
throw new RequiredFilterException();
}