如何避免很多if else条件

时间:2012-04-16 14:14:19

标签: java if-statement refactoring

我已经阅读了很多关于代码重构和避免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();
     }

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

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

谢谢。

8 个答案:

答案 0 :(得分:44)

尝试查看策略模式。

  • 创建一个用于处理响应的接口类(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
   }
}

在您需要创建处理程序的地方:

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

您收到回复的地方:

IResponseHandler responseHandler = strategyHandlers.get(soapResponse);
responseHandler.handleResponse(xxp);

答案 1 :(得分:25)

在这种特殊情况下,由于代码对于所有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

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

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();
}

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

答案 2 :(得分:8)

在Java 7中,您可以在字符串上切换。你可以使用它,如果你可以使用它; - )

答案 3 :(得分:5)

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

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

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();

答案 4 :(得分:4)

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

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

首先你可以重复代码

if (soapResponse.equals("EditorialOffice")
||soapResponse.equals("EditorialBoard")
||soapResponse.equals("AdvisoryBoard")){ 

你能做的另一件好事就是玩开关站点,如:

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

另外你应该考虑将测试分解为小功能:

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();
                    }
    ....}

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

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

答案 5 :(得分:4)

你没有提到你是否可以使用Java 7.从那个java版本开始,你可以使用Strings in switch statements

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

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

然后您只需从地图中选择正确的策略并使用它:

String soapResponse = xpp.getName();
Department department = strategyMap.get(soapResponse);
department.addText(xpp.getText());

Department当然是接口......

答案 6 :(得分:3)

您可以使用三个实现创建一个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();
            }
        }
    }
}

您的代码变为

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);
}

答案 7 :(得分:2)

您可以定义如下的枚举:

public enum SoapResponseType {
    EditorialOffice(1, "description here") {
        public void handle(XmlPullParser xpp) {
            //do something you want here
            return null;
        }
    },
    EditorialBoard(2, "description here") {
        public void handle(XmlPullParser xpp) {
            //do something you want here
            return null;
        }
    },
    AdvisoryBoard(3, "description here") {
        public void handle(XmlPullParser xpp) {
            //do something you want here
            return null;
        }
    };

    public static SoapResponseType nameOf(String name) {
        for (SoapResponseType type : values()) {
            if (type.getName().equalsIgnoreCase(name)) {
                return type;
            }
        }
        return null;
    }

    public void handle(XmlPullParser xpp) {
        return null;
    }
}

使用上面的枚举:

SoapResponseType type = SoapResponseType.nameOf("input string");
if (type != null) {
    type.handle(xpp);
}

这是干净的代码,不是吗!