在不使用许多if语句的情况下编写代码

时间:2020-06-22 22:16:31

标签: java

这是关于if和else if的代码逻辑,

Search search = new Search(); 
Request request = new Request()
Client client = new Client();

String typeA = data.getTypeA();  // data object passing as argument to method
String typeB = data.getTypeB();
String typeC = data.getTypeC();
String typeD = data.getTypeD();

if(typeA!=null) {
    search.setType("A");  
    search.setValue(typeA);  // Type A value   
    request.setSerach(search);  
    return client.invokeTypeA(request);
}
else if(typeB!=null){
    search.setType("B");  
    search.setValue(typeB);  // Type B value   
    request.setSerach(search);  
    return client.invokeTypeB(request); 
}
else if (typeC!=null){
      ... 
      ... 
    return client.invokeTypeC(request); 
}
else if(typeD!=null){
      ... 
      ... 
    return client.invokeTypeD(request); 
}

这里的代码工作正常,但是我只需要知道使用其他任何方法即可实现相同功能,而无需使用if和else if。当然可以使用诅咒开关,但是我敢肯定,还有其他一些不错的方法。至少,如果我不了解其他方法,我不会期望确切的解决方案,我将对此进行深入研究并提高我的编码技能。请为我的功能提供一些另类的替代方法。

2 个答案:

答案 0 :(得分:0)

据我了解,在您的代码中,您正在要求配置以设置搜索。

因此,在面向对象的开发风格中,您会避免问类似以下问题:

if (type is X) 
   ...
else if (type is Y) 
   ...
else if (type is Z)

这被认为是不良的OO设计。

OO方法是使用动态调度。因此,您将拥有一个由UI配置的 Filter 类,然后将其应用到搜索中,如下所示:

filter.applyOn(search);
request.setSearch(search);
client.invoke(search);

然后添加一个枚举或类,如下所示:

DataType type = data.getType();

// where
abstract class DataType {
    // lambda
    public static DataType instanceFor(....) {
        return (search) ->
            {  search.setType(this.getName()); .... };   
    }

    public abstract void applyOn(Search search);
}

但是如果这不可能,并且您必须使用一些类似if的语句,请考虑使用Map来代替:

map.put("valueA", this::methodA);
map.put("valueB", this::methodB);
map.put("valueC", this::methodC);

map.computeIfAbsent(data.getType(), (s,r,c) -> {}).apply(search,request,client);

那是避免ifs的另一种方式。

答案 1 :(得分:-1)

没有“插入”答案;如果有的话,那意味着有两种方法可以做完全相同的事情,那将是糟糕的语言设计,所以这是一件好事。

当然,还有其他选择,但是它们并不是“插入”的-它们需要更改if / elseif块周围的代码。

例如,假设数据具有.getTypeInfos(),该数据返回TypeInfo对象。 TypeInfo类似于:

@Value
public class TypeInfo {
    String resultText;
    SearchType type;
}

public enum SearchType {
    A, B, C, D;
}

注意:TypeInfo是一个可怕的名字。但是,您的代码段已删除所有上下文信息。

那么你可以做:

for (TypeInfo info : data.getTypeInfos()) {
    if (info.getResultText() == null) continue;
    search.setType(info.getType());
    search.setValue(info.getResultText());
    request.setSearch(search);
    return client.invoke(request);
}

Java具有很高的标称性和结构性;一旦您决定制作一个名为getTypeA的方法和一个名为getTypeB的方法,就可以了-现在很难尝试在名称概念中编写代码要调用的方法的参数是一个参数。所以,不要那样做。如果getTypeA()getTypeB()的结构相似,则创建一个名为getType(Type t)的方法。

如果您编写了一系列名为typeAtypeB等的方法,是的,您往往会遇到大量的代码和大量的长if / elseif链。这就是为什么您通常不应该这样做的原因。