如何避免很多if else条件

Mil*_*loš 38 java refactoring if-statement

我已经阅读了很多关于代码重构和避免if else语句的主题.实际上,我有一个班级,我使用了很多if - else条件.

更多细节:我正在使用pull解析器,在我的soap响应的每一行,我将检查是否有我感兴趣的标签,如果没有,检查另一个标签等:

 if(eventType == XmlPullParser.START_TAG) {
            soapResponse= xpp.getName().toString();

            if (soapResponse.equals("EditorialOffice")){  
                eventType = xpp.next();
                if (xpp.getText()!=null){
                editorialOffice += xpp.getText();
                }
            }   
            else if (soapResponse.equals("EditorialBoard")){  
                eventType = xpp.next();
                if (xpp.getText()!=null){
                editorialBoard += xpp.getText();
                }
            }
            else if (soapResponse.equals("AdvisoryBoard")){  
                eventType = xpp.next();
                if (xpp.getText()!=null){
                advisoryBoard += xpp.getText();
                }
            }   
        }
        eventType = xpp.next();
     }
Run Code Online (Sandbox Code Playgroud)

现在,我想使用somethimg else,而不是那些if else条件,但我不知道是什么.

你能给我一个例子或一个好的教程页面吗?

谢谢.

hwc*_*rwe 47

试着看一下策略模式.

  • 创建一个用于处理响应的接口类(IMyResponse)
    • 使用此IMyResponse创建AdvisoryBoardResponse,EditorialBoardResponse类
  • 创建一个字典,其中soapresponse值为关键,策略为值
  • 然后,您可以通过从字典中获取它来使用IMyResponse类的方法

小例子:

// Interface
public interface IResponseHandler {
   public void handleResponse(XmlPullParser xxp);

}

// Concrete class for EditorialOffice response
private class EditorialOfficeHandler implements IResponseHandler {
   public void handleResponse(XmlPullParser xxp) {
       // Do something to handle Editorial Office response
   }
}

// Concrete class for EditorialBoard response
private class EditorialBoardHandler implements IResponseHandler {
   public void handleResponse(XmlPullParser xxp) {
       // Do something to handle Editorial Board response
   }
}
Run Code Online (Sandbox Code Playgroud)

在您需要创建处理程序的位置:

Map<String, IResponseHandler> strategyHandlers = new HashMap<String,IResponseHandler>();
strategyHandlers.put("EditorialOffice", new EditorialOfficeHandler());
strategyHandlers.put("EditorialBoard", new EditorialBoardHandler());
Run Code Online (Sandbox Code Playgroud)

你收到回复的地方:

IResponseHandler responseHandler = strategyHandlers.get(soapResponse);
responseHandler.handleResponse(xxp);
Run Code Online (Sandbox Code Playgroud)

  • 也许这适用于更复杂的多条件决策.但对于这种特殊情况,这种感觉不是太重了吗?哎呀,在这种特殊情况下,我甚至更喜欢"if,then then else if"这个解决方案(虽然存在其他更简单的解决方案). (2认同)
  • +1:我已经为你处理XML应用程序的程序提出了很多建议. (2认同)

Kev*_*ker 26

在这种特殊情况下,由于除了要附加的String之外,代码对于所有3种情况基本相同,因此我将为每个构建的字符串创建一个映射条目:

Map<String,String> map = new HashMap<String,String>();
map.put("EditorialOffice","");
map.put("EditorialBoard","");
map.put("AdvisoryBoard","");
// could make constants for above Strings, or even an enum
Run Code Online (Sandbox Code Playgroud)

然后将您的代码更改为以下内容

if(eventType == XmlPullParser.START_TAG) {
    soapResponse= xpp.getName().toString();
    String current = map.get(soapResponse);
    if (current != null && xpp.getText()!=null) {
        map.put( soapResponse, current += xpp.getText());
    }
    eventType = xpp.next();
}
Run Code Online (Sandbox Code Playgroud)

没有"如果......那么......别的".甚至没有增加策略模式的多个类的复杂性等.地图是你的朋友.策略在某些情况下很棒,但这个很简单,可以在没有的情况下解决.


Pet*_*háč 8

在Java 7中,您可以在字符串上进行SWITCH.你可以使用它,如果你可以使用;-)

  • +1表示"你可以使用它,如果你可以使用它." 如果我们有鸡蛋,我们可以吃火腿和鸡蛋,如果我们有火腿. (17认同)
  • 如果你想让代码更干净,开关不会让它更干净 (3认同)

Jen*_*der 6

您可以创建一个具有三个实现的 ResponseHandler 接口,一个用于 if/else 构造的每个分支。

然后有一个映射将不同的soapResponses映射到一个处理程序,或者一个包含所有处理程序的列表(如果它可以处理该soapResponse)。

您还应该能够将一些样板代码移动到响应处理程序类的常见的可能抽象实现中。

通常情况下,这种情况有很多变化。通过利用代码复制,实际上只需要一种实现:

class ResponseHandler{
    String stringToBuild = "" // or what ever you need
    private final String matchString

    ResponseHandler(String aMatchString){
        matchString = aMatchString
    }
    void handle(XppsType xpp){
        if (xpp.getName().toString().equals(matchString){
            eventType = xpp.next();
            if (xpp.getText()!=null){
                 editorialOffice += xpp.getText();
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

你的代码变成

List<ResponseHandler> handlers = Arrays.asList(
    new ResponseHandler("EditorialOffice"),
    new ResponseHandler("EditorialBoard"),
    new ResponseHandler("AdvisoryBoard"));
if(eventType == XmlPullParser.START_TAG) {
    for(ResponseHandler h : handlers)
        h.handle(xpp);
}
Run Code Online (Sandbox Code Playgroud)


Cri*_*ian 5

除了zzzzzzz(等)的评论之外......请记住,你正在使用XmlPullParser,它会让你像你所拥有的那样编写丑陋的代码.您可以注册一些可以拆分代码并使其"更好"的回调,但如果可能的话,只需使用SimpleXML库或类似的.

此外,您可以重构代码,使其更具可读性和更简洁.例如,为什么要xpp.next()在每个if语句中调用?为什么不在外面只调用一次:

if(eventType == XmlPullParser.START_TAG) {
    soapResponse= xpp.getName().toString();
    if (soapResponse.equals("EditorialOffice") && xpp.getText()!=null){  
        editorialOffice += xpp.getText();
    }   
    else if (soapResponse.equals("EditorialBoard") && xpp.getText()!=null){  
        editorialBoard += xpp.getText();
    }
    else if (soapResponse.equals("AdvisoryBoard") && xpp.getText()!=null){  
        advisoryBoard += xpp.getText();
    }   
}
eventType = xpp.next();
Run Code Online (Sandbox Code Playgroud)


Jas*_*ers 5

这是一个巨大的问题,没有真正的答案。(而且我不经常使用肥皂)

这里只是一些基于您的代码的想法:

首先,您可以对重复代码进行分组

if (soapResponse.equals("EditorialOffice")
||soapResponse.equals("EditorialBoard")
||soapResponse.equals("AdvisoryBoard")){ 
Run Code Online (Sandbox Code Playgroud)

您可以做的另一件好事是玩转开关,例如:

switch(soapResponse){
case "EditorialOffice":
case "EditorialBoard":
case "AdvisoryBoard":
eventType = xpp.next();
                if (xpp.getText()!=null){
                advisoryBoard += xpp.getText();
                }
break;
Run Code Online (Sandbox Code Playgroud)

您还应该考虑将您的测试分解为小功能:

public bool interestingTag(string s){
return (soapResponse.equals("EditorialOffice")
    ||soapResponse.equals("EditorialBoard")
    ||soapResponse.equals("AdvisoryBoard"));
}

    public processData(xpp){
    eventType = xpp.next();
                    if (xpp.getText()!=null){
                    editorialBoard += xpp.getText();
                    }
    ....}
Run Code Online (Sandbox Code Playgroud)

这样你就可以在一个 while 循环中处理你所有的答案,如果 else 变成一个 5~10 行的函数,你就会超长

但正如我所说,有很多好方法可以做同样的事情


Ala*_*eet 5

您还没有提到您是否可以或确实使用 Java 7。从该 Java 版本开始,您可以在 switch 语句中使用字符串

除此之外,封装每个案例的逻辑是一个好主意,例如:

Map<String, Department> strategyMap = new HashMap<String, Department>();
strategyMap.put("EditorialOffice", new EditorialOfficeDepartment());
strategyMap.put("EditorialBoard", new EditorialBoardDepartment());
strategyMap.put("AdvisoryBoard", new AdvisoryBoardDepartment());
Run Code Online (Sandbox Code Playgroud)

然后您可以简单地从地图中选择正确的策略并使用它:

String soapResponse = xpp.getName();
Department department = strategyMap.get(soapResponse);
department.addText(xpp.getText());
Run Code Online (Sandbox Code Playgroud)

Department 当然是在界面...