我如何重构这个有多个if-else的代码?

3vpjnl9f  于 2021-07-09  发布在  Java
关注(0)|答案(2)|浏览(310)

我有一节课有很多“如果不是”。我不知道如何重构它。我想工厂模式,但我不知道如何实现它。有人帮我吗?

@Override
    public Predicate toPredicate(@NotNull Root<E> root, @NotNull CriteriaQuery<?> cq, @NotNull CriteriaBuilder cb) {

        List<Predicate> predicates = new ArrayList<>();

        for (SearchCriteria criteria : criteriaList) {
            if (criteria.getValue() == null) {
                predicates.add(cb.isTrue(cb.literal(true)));
            } else if (criteria.getOperation().equals(GREATER_THAN)) {
                predicates.add(cb.greaterThan(root.get(criteria.getKey()).as(criteria.getKey().getClass()), criteria.getValue().toString()));
            } else if (criteria.getOperation().equals(LESS_THAN)) {
                predicates.add(cb.lessThan(root.get(criteria.getKey()).as(criteria.getKey().getClass()), criteria.getValue().toString()));
            } else if (criteria.getOperation().equals(GREATER_THAN_EQUAL)) {
                predicates.add(cb.greaterThanOrEqualTo(root.get(criteria.getKey()).as(criteria.getKey().getClass()), criteria.getValue().toString()));
            } else if (criteria.getOperation().equals(LESS_THAN_EQUAL)) {
                predicates.add(cb.lessThanOrEqualTo(root.get(criteria.getKey()).as(criteria.getKey().getClass()), criteria.getValue().toString()));
            } else if (criteria.getOperation().equals(NOT_EQUAL)) {
                predicates.add(cb.notEqual(root.get(criteria.getKey()).as(criteria.getKey().getClass()), criteria.getValue()));
            } else if (criteria.getOperation().equals(EQUAL)) {
                predicates.add(cb.equal(root.get(criteria.getKey()).as(criteria.getKey().getClass()), criteria.getValue()));
            } else if (criteria.getOperation().equals(MATCH)) {
                predicates.add(cb.like(cb.lower(root.get(criteria.getKey())), "%" + criteria.getValue().toString().toLowerCase() + "%"));
            } else if (criteria.getOperation().equals(MATCH_END)) {
                predicates.add(cb.like(cb.lower(root.get(criteria.getKey())), criteria.getValue().toString().toLowerCase() + "%"));
            } else if (criteria.getOperation().equals(MATCH_START)) {
                predicates.add(cb.like(cb.lower(root.get(criteria.getKey())), "%" + criteria.getValue().toString().toLowerCase()));
            } else if (criteria.getOperation().equals(IN)) {
                predicates.add(cb.in(root.get(criteria.getKey())).value(criteria.getValue()));
            } else if (criteria.getOperation().equals(NOT_IN)) {
                predicates.add(cb.not(root.get(criteria.getKey())).in(criteria.getValue()));
            }
        }
        return cb.and(predicates.toArray(Predicate[]::new));
    }
7fyelxc5

7fyelxc51#

工厂模式是一种创造性的模式。因此,它用于构造一个对象,不同的用途之间需要存在一些公共接口。这并不直接适用于你的案子。
假设您可以编辑criteriabuilder,则可以执行以下操作:
(可选)更换 criteria.getOperation() , criteria.getKey() , criteria.value() 带局部变量 op , key 以及 value 使代码更具可读性。
更新 CriteriaBuilder 公开一个方法,比如 build(root, key, value, op) 并将如何构建每个标准的代码移到这个方法中。
在你的 toPredicate() ,你可以简单地 predicates.add(cb.build(root, key, value, op)) .
你可能会说,这种方法只会让巨人陷入困境 cb.build() 方法;然而,这离更清晰的代码又近了一步。 cb.build() 基本上是您正在寻找的工厂方法,以及调用者( toPredicate() )不必知道建立标准的逻辑。
您可以继续改进if-else逻辑 cb.build() 因为您可以直接访问 CriteriaBuilder . 如果不了解代码,很难判断下一步是什么 CriteriaBuilder .

um6iljoc

um6iljoc2#

SearchCriteria.java 接口,类似于:

public interface SearchCriteria {

    String getOperation();
}

而不是编写将实现此接口的标准类,例如:

public class LessThanCriteria implements SearchCriteria {

    public static final String LESS = "some value";

    @Override
    public String getOperation() {
        return LESS;
    }
}

public class GreatherThanCriteria implements SearchCriteria {

    public static final String GREATER_THAN = "some value";

    @Override
    public String getOperation() {
        return GREATER_THAN;
    }
}

发射型计算机断层扫描仪。
而不是写 PredicateFactory.java 类,该类封装用于基于搜索条件创建 predicate 对象的逻辑。

public class PredicateFactory {

    public static final String LESS = "some value";
    public static final String LESS_THAN_EQUAL = "some value";
    public static final String NOT_EQUAL = "some value";
    public static final String EQUAL = "some value";
    public static final String MATCH = "some value";
    public static final String MATCH_END = "some value";
    public static final String MATCH_START = "some value";
    public static final String IN = "some value";
    public static final String NOT_IN = "some value";

    public static Predicate getPredicate(SearchCriteria criteria){
        if(criteria == null){
            return null;
        }
        if(criteria.getOperation().equalsIgnoreCase(LESS)){
            return new Predicate(); // here you create predicate object that 
                                          // you want, 
                                        //based on criteria

        } else if(criteria.getOperation().equalsIgnoreCase(LESS_THAN_EQUAL)){
            return new Predicate();

        } else if(criteria.getOperation().equalsIgnoreCase(NOT_EQUAL)){
            return new Predicate();
        }
        else if(criteria.getOperation().equalsIgnoreCase(EQUAL)){
             return new Predicate();
        }
        else if(criteria.getOperation().equalsIgnoreCase(MATCH)){
            return new Predicate();
        }
        else if(criteria.getOperation().equalsIgnoreCase(MATCH_END)){
            return new Predicate();
        }
        else if(criteria.getOperation().equalsIgnoreCase(MATCH_START)){
            return new Predicate();
        }
        else if(criteria.getOperation().equalsIgnoreCase(IN)){
            return new Predicate();
        }
        else if(criteria.getOperation().equalsIgnoreCase(NOT_IN)){
            return new Predicate();
        }
        return null;
    }

}

最后,在foor循环中使用这个工厂类:

for (SearchCriteria criteria : criteriaList) {
      Predicate p = PredicateFactory.getPredicate(criteria);
      predicates.add(p); 

}

相关问题