优化Java中的多个if-else条件

时间:2018-06-13 11:41:26

标签: java if-statement

我有一个REST API,它将根据特定的搜索条件提供搜索结果。 用户可以使用部门ID,用户ID和加入日期进行搜索。 所以在这里,用户可以搜索7种不同的组合。

  1. 仅使用部门ID
  2. 进行搜索
  3. 仅使用用户ID
  4. 进行搜索
  5. 仅使用加入日期搜索
  6. 使用部门ID& amp;用户标识
  7. 使用用户ID搜索&加入日期
  8. 使用部门ID& amp;加入日期
  9. 搜索所有3个条件(部门ID,用户ID和加入日期)
  10. 根据我们的应用程序的当前设计,对于每个标准,我将不得不以不同的顺序调用不同的服务以获取信息。

    例如:我们有一个包含用户详细信息的现有用户服务,一个包含详细信息的部门服务。因此,如果用户只搜索用户ID,我会直接转到UserService。如果用户使用部门ID&用户我首先要查询Dept服务,然后查询用户服务。

    我目前的代码是:

    if(Util.hasOnlyUserId(searchCriteria)) {
            searchResponse = searchWithUserId(searchRequest);
        } else if(Util.hasOnlyJoinedDate(searchCriteria)) {
            searchResponse = searchWithDate(searchRequest);
        } else if (Util.hasOnlyDeptID(searchCriteria)) {
            searchResponse = searchWithDeptId(searchRequest);
        } else if (Util.hasUserIdAndDeptId(searchCriteria)) {
            searchResponse = searchWithUserIdAndDeptId(searchRequest);
        } else if (Util.hasUserIdAndDate(searchCriteria)){
            searchResponse = searchWithUserIdAndDate(searchRequest);
        } else if (Util.hasDeptIdAndDate(searchCriteria)) {
            searchResponse = searchWithDeptIdAndDate(searchRequest);
        } else if (Util.hasAllCriteria(searchCriteria)) {
            searchResponse = searchWithAllCriteria(searchRequest);
        }
    

    这里,searchCriteria是我的请求对象(PO​​JO),它将这些搜索元素作为私有成员。

    searchResponse这里是一种SearchResponse对象,它是API的实际响应,它包含用户的详细信息,如name,id,position,lastSalaryDrawn,CommuteType,MaritalStatus和Last Promoted Date

    我一直试图优化这个多个if-else条件换句话说,避免出现这种多重条件。 我试图将它们分开并将它们分成不同的方法。但这并不令我满意,似乎它处于一种不可优化的状态。

    关于如何做到这一点的任何想法将不胜感激。

    编辑:我们正在使用JPA与MySQL进行交互。 这里的问题是我不会直接从DB获取信息。因此,构建动态查询可能不起作用。 需要从多个微服务中获取信息,这些服务将调用其本机数据库并将所需信息作为响应发送。 我希望这是有道理的。

3 个答案:

答案 0 :(得分:1)

您可以将代码移动到执行条件的位置并动态构建查询:

public SearchResponse searchWithCriteria(Criteria searchCriteria) {
    StringBuilder query = new StringBuilder("SELECT * FROM ... WHERE ...");
    if (util.hasUserId(searchCriteria))
        query.append(" AND userId = :userId");
    if (util.hasJoinedDate(searchCriteria))
        query.append(" AND joinedDate = :joinedDate");
    ...
    PreparedStatement stmt = connection.prepareStatement(query);
    if (util.hasUserId(searchCriteria))
        stmt.setString("userId", searchCriteria.getUserId());
    if (util.hasJoinedDate(searchCriteria))
        stmt.setDate("joinedDate", searchCriteria.getJoinedDate());
    ...
    ResultSet res = stmt.executeQuery();
    ...
}

答案 1 :(得分:0)

可以使用Strategy pattern优化代码。

答案 2 :(得分:0)

此处可以使用各种模式,您必须根据搜索代码的外观选择一种模式。有些人已经提到了战略和责任链模式。您可以看到的另一个是Builder模式。它允许您拥有仅在需要时指定的可选部件,以构建最终对象。

因此,当您添加更多的过滤条件时,您可以拥有一个SearchBuilder类来更新有关搜索的信息。它可能包含setUserId(...)setDeptId(...)等方法。

例如:如果将搜索转换为PreparedStatement中的纯SQL查询,则只要设置了其中一个过滤字段,构建器就会存储它们(它们将以null开头) 。因此,如果在构建器中调用了setUserId()和setDeptId(),那么构建器中的那些将不是null,并且您生成一个带有字符串的查询(为您想要的每个额外字段附加AND ...过滤器): select * from users where id=? AND dept_id=?

SearchBuilder可以提供build()方法,然后返回一个携带查询的Search对象,甚至可以提供执行查询的方法,或者您需要做的任何事情。