如何解决如何重构具有多个if-else的代码?
我有一堂课,上面有很多“如果不是”。我不知道如何重构它。我考虑过工厂模式,但是我不知道如何实现。有人帮我吗?
@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));
}
解决方法
编写SearchCriteria.java
界面,如下所示:
public interface SearchCriteria {
String getOperation();
}
比编写将实现此接口的Criteria类,如下所示:
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;
}
}
ect。
比起编写PredicateFactory.java
类,该类封装了用于基于SearchCriteria创建谓词对象的逻辑。
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循环中使用此Factory类:
for (SearchCriteria criteria : criteriaList) {
Predicate p = PredicateFactory.getPredicate(criteria);
predicates.add(p);
}
,
Factory Pattern是一种创造模式。因此,它用于构造对象,并且各种用途之间需要存在一些公共接口。目前,这并不直接适用于您的情况。
假设您可以编辑CriteriaBuilder,则可以执行以下操作:
- (可选)将
criteria.getOperation()
,criteria.getKey()
,criteria.value()
替换为局部变量op
,key
和value
,以使代码更具可读性。 - 更新
CriteriaBuilder
,以暴露诸如build(root,key,value,op)
之类的单个方法,并将如何构建每个条件的代码移入该方法。 - 在您的
toPredicate()
中,您可以简单地predicates.add(cb.build(root,op))
。
您可能会争辩说,这种方法只会将巨大的if-else块移至cb.build()
方法中;但是,这离更清洁的代码又近了一步。 cb.build()
本质上就是您要寻找的工厂方法,而调用方(toPredicate()
)不必了解建立条件的逻辑。
由于可以直接访问cb.build()
中的私有字段,因此可以继续将if-else逻辑改进为CriteriaBuilder
。不看CriteriaBuilder
的代码就很难说出下一步是什么。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。