避免复杂if-else分支的最佳方法-Java
我有一个RESTAPI,它使用几个参数(如requestparams)来搜索实体。此搜索可能有多种变体。以下方法在结尾处获取调用,以搜索具有给定参数的实体避免复杂if-else分支的最佳方法-Java,java,if-statement,null,Java,If Statement,Null,我有一个RESTAPI,它使用几个参数(如requestparams)来搜索实体。此搜索可能有多种变体。以下方法在结尾处获取调用,以搜索具有给定参数的实体 public List<Person> searchPerson(final String name, final String city, final String state, final String code) { if( name != null && city != nu
public List<Person> searchPerson(final String name,
final String city, final String state, final String code) {
if( name != null && city != null && state != null && code != null ){
//Search person in database with above all parameters
//personRepositoy is spring data repository.
personRepositoy.findByNameAndCityAndStateAndCode(name, city, state, code);
} else if( city != null && state != null && code != null){
personRepositoy.findByCityAndStateAndCode(name, city, state, code)
}
}
public List searchPerson(最终字符串名,
最终字符串城市、最终字符串状态、最终字符串代码){
if(name!=null&&city!=null&&state!=null&&code!=null){
//使用以上所有参数在数据库中搜索人员
//personRepositoy是spring数据存储库。
personRepositoy.FindBynameandCity和dStateandCode(姓名、城市、州、代码);
}如果(城市!=null&&state!=null&&code!=null){
personRepositoy.FindBycityandStates和code(名称、城市、州、代码)
}
}
这里有没有一种方法可以避免复杂的(容易出错,不容易重构)分支?可能正在使用集合或函数式编程概念?我真的不喜欢编写这种分支代码(因为它们很难维护)您可以为此创建自己的实用程序,如下所示:
public static boolean requireNonNull(Object... objects) {
for(Object obj : objects) {
if(obj == null) return false;
}
return true;
}
示例用法
public List<Person> searchPerson(final String name, final String city,
final String state, final String code) {
if(MyUtilityClass.requireNonNull(name, city, state, code)) {
//Search person in database with above all parameters
//personRepositoy is spring data repository.
personRepositoy.findByNameAndCityAndStateAndCode(name, city, state, code);
} else if(MyUtilityClass.requireNonNull(city, state, code)) {
personRepositoy.findByCityAndStateAndCode(city, state, code)
}
}
public List searchPerson(最终字符串名称、最终字符串城市、,
最终字符串状态,最终字符串代码){
if(MyUtilityClass.requireNonNull(名称、城市、州、代码)){
//使用以上所有参数在数据库中搜索人员
//personRepositoy是spring数据存储库。
personRepositoy.FindBynameandCity和dStateandCode(姓名、城市、州、代码);
}else if(MyUtilityClass.requireNonNull(城市、州、代码)){
personRepositoy.findByCityAndStateAndCode(城市、州、代码)
}
}
您可以为此创建自己的实用程序,如下所示:
public static boolean requireNonNull(Object... objects) {
for(Object obj : objects) {
if(obj == null) return false;
}
return true;
}
示例用法
public List<Person> searchPerson(final String name, final String city,
final String state, final String code) {
if(MyUtilityClass.requireNonNull(name, city, state, code)) {
//Search person in database with above all parameters
//personRepositoy is spring data repository.
personRepositoy.findByNameAndCityAndStateAndCode(name, city, state, code);
} else if(MyUtilityClass.requireNonNull(city, state, code)) {
personRepositoy.findByCityAndStateAndCode(city, state, code)
}
}
public List searchPerson(最终字符串名称、最终字符串城市、,
最终字符串状态,最终字符串代码){
if(MyUtilityClass.requireNonNull(名称、城市、州、代码)){
//使用以上所有参数在数据库中搜索人员
//personRepositoy是spring数据存储库。
personRepositoy.FindBynameandCity和dStateandCode(姓名、城市、州、代码);
}else if(MyUtilityClass.requireNonNull(城市、州、代码)){
personRepositoy.findByCityAndStateAndCode(城市、州、代码)
}
}
为清晰起见,请按以下代码编写
if(name!=null)
{
if(city!=null)
{
if(state!=null
{
if(code!=null)
{
// do search using all
}
//search using name , city , code
}
// search using name , city
}
//search using name only
}
为清楚起见,代码如下所示
if(name!=null)
{
if(city!=null)
{
if(state!=null
{
if(code!=null)
{
// do search using all
}
//search using name , city , code
}
// search using name , city
}
//search using name only
}
城市!=空和状态!=空和空代码!=null
可能保存在变量中
boolean cityStateCodeGiven = city != null && state != null && code != null;
if(name != null && cityStateCodeGiven) {
// name, city, state, code are given
} else if (cityStateCodeGiven) {
// city, state, code are given
}
您不需要重新检查某些条件两次或更多次
例如,cityStateCodeGiven
可能被拆分为cityStateGiven+codeGiven
<代码>名称!=null&&cityStateCodeGiven可以分组为nameCityStateCodeGiven
变量的名称将告诉变量检查哪些条件
此外,您可以将这些声明放在方法的开头。它将给出一些关于您稍后将在代码中使用的方法的提示
boolean cityStateCodeGiven = city != null && state != null && code != null;
boolean nameCityStateCodeGiven = cityStateCodeGiven && name != null;
城市!=空和状态!=空和空代码!=null
可能保存在变量中
boolean cityStateCodeGiven = city != null && state != null && code != null;
if(name != null && cityStateCodeGiven) {
// name, city, state, code are given
} else if (cityStateCodeGiven) {
// city, state, code are given
}
您不需要重新检查某些条件两次或更多次
例如,cityStateCodeGiven
可能被拆分为cityStateGiven+codeGiven
<代码>名称!=null&&cityStateCodeGiven可以分组为nameCityStateCodeGiven
变量的名称将告诉变量检查哪些条件
此外,您可以将这些声明放在方法的开头。它将给出一些关于您稍后将在代码中使用的方法的提示
boolean cityStateCodeGiven = city != null && state != null && code != null;
boolean nameCityStateCodeGiven = cityStateCodeGiven && name != null;
如果不知道不同的检查是如何相互作用的,就很难判断 无论如何,以下文章为您提供了5种不同的解决方案(模式),以使if-else条件更具可读性:
希望您可以在代码中使用其中的一个检查。如果不知道不同的检查是如何相互作用的,就很难判断 无论如何,以下文章为您提供了5种不同的解决方案(模式),以使if-else条件更具可读性:
希望您可以在代码中使用其中一个。我建议您更广泛地研究这个问题。我可以期待以下事情:
SearchPersonRequest
然后,您有了这个对象,它可能有一个特殊的行为,比如为搜索引擎创建搜索请求,即SpringData
。当您有多个字段用于使用多个组合进行搜索时,使用JpaSpecificationExecutor
非常灵活
这是我的主要观点。作为一个例子,我给出了我的第一种方法(您可以看到Lombok
annotations,它只是为了简化代码;不需要使用它):
SearchPersonRequest
@Builder
public class SearchPersonRequest {
private String name;
private String city;
private String state;
private String code;
public Specification<Person> createSpecification() {
List<Specification<Person>> specifications = getSpecifications();
Specifications<Person> spec = null;
if (!specifications.isEmpty()) {
Iterator<Specification<Person>> it = specifications.iterator();
spec = where(it.next());
while (it.hasNext()) {
spec = spec.and(it.next());
}
}
return spec;
}
private List<Specification<Person>> getSpecifications() {
return Arrays.stream(Field.values())
.filter(field -> field.isExists(this))
.map(field -> (Specification<Person>)(root, query, builder) -> builder.equal(root.get(field.id), field.get.apply(this)))
.collect(Collectors.toList());
}
@RequiredArgsConstructor(access = AccessLevel.PACKAGE)
private enum Field {
NAME("name", request -> request.name),
CITY("city", request -> request.city),
STATE("state", request -> request.state),
CODE("code", request -> request.code);
private final String id;
private final Function<SearchPersonRequest, String> get;
private boolean isExists(SearchPersonRequest request) {
return StringUtils.isNotBlank(get.apply(request));
}
}
}
@Builder
公共类SearchPersonRequest{
私有字符串名称;
私人城市;
私有字符串状态;
私有字符串码;
公共规范createSpecification(){
列表规格=getSpecifications();
规格规格=空;
如果(!specifications.isEmpty()){
迭代器it=规范。迭代器();
spec=where(it.next());
while(it.hasNext()){
spec=spec.and(it.next());
}
}
返回规格;
}
私有列表getSpecifications(){
返回Arrays.stream(Field.values())
.filter(字段->字段.isExists(此))
.map(field->(规范)(root、query、builder)->builder.equal(root.get(field.id)、field.get.apply(this)))
.收集(