如何简化if else语句中的重复代码?

4

我是一个有用的助手,可以为您进行文本翻译。

我认为这是Web项目中非常常见的情况。假设存在这样的实体:

//JAVA code
@Data
class Entity{

    private String a;
    private String aExt;

    private String b;
    private String bExt;

    private String c;
    private String cExt;

    ... something more ...
}

为了某种目的,我需要根据传递的参数从 Entity 中获取部分值,例如:
public ViewObject foo(Entity entity, String condition){

    ViewObject vo = new ViewObject();

    if("aRelated".equals(condition)){
        vo.setValue1(entity.getA());
        vo.setValue2(entity.getAExt());
    }
    else if("bRelated".equals(condition)){
        vo.setValue1(entity.getB());
        vo.setValue2(entity.getBExt());
    }
    else if(cRelated".equals(condition)){
        vo.setValue1(entity.getC());
        vo.setValue2(entity.getCExt());
    }
    ... else statement if there are other values ....

    return vo;
}

我知道可以使用switch-case语句来减少foo()中的一些单词,但与if-else相比没有本质区别,特别是当Entity有许多变量时。
例如,foo()仅是一个视图对象构建器,但我的项目更加复杂,每个if-else语句中都有许多重复的代码,只有不同的变量名称。
如何减少上述重复代码?

1
您可以使用Map、Set或任何Java.lang.Object子类型,并返回它。 - Vinod Bokare
4个回答

4
你可以尝试创建两个哈希表:
// name these properly!
HashMap<String, Function<Entity, String>> valueMap = new HashMap<>();
HashMap<String, Function<Entity, String>> extMap = new HashMap<>();

添加以下键值对:

// valueMap
"aRelated" - Entity::getA
"bRelated" - Entity::getB
"cRelated" - Entity::getC

// extMap
"aRelated" - Entity::getAExt
"bRelated" - Entity::getBExt
"cRelated" - Entity::getCExt

现在,您可以不使用if语句来完成这个操作:
vo.setValue1(valueMap.get(condition).apply(entity));
vo.setValue2(extMap.get(condition).apply(entity));

谢谢,这看起来更清晰了,我刚找到了一种方法在一行代码中添加多个键值对。链接 - scott

1
另一个选项是使用反射:
import java.lang.reflect.Method;
import java.lang.reflext.InvocationTargetException;

...

public ViewObject foo(Entity e, String c) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
  String[] methodNames = { "get" + c.substring(0,1).toUpperCase(), "get" + c.substring(0,1).toUpperCase() + "Ext" }; 
  Method[] methods = { e.getClass().getDeclaredMethod(methodNames[0]), e.getClass().getDeclaredMethod(methodNames[1]) };
  ViewObject vo = new ViewObject();                                                                                                   

  vo.setValue1((String)methods[0].invoke(e));                                                                                         
  vo.setValue2((String)methods[1].invoke(e));                                                                                         

  return vo;                                                                                                                          
}

尽管我必须承认,我个人更喜欢其他答案所展示的地图方式,因为它提供了更多的选项。

0
使用Map可以解决这个问题:
class EntityPart {
    String s;
    String sExt;
}

class Entity {
    Map<String,EntityPart> m = new HashMap<>();
    m.add("aRelated",new EntityPart());
    m.add("bRelated",new EntityPart());
    ....
}

public ViewObject foo(Entity entity, String condition) {
    ViewObject vo = new ViewObject();
    EntityPart ep = entity.m.get(condition);
    vo.setValue1(ep.s);
    vo.setValue2(ep.sExt);
    return vo;
}

0
将实体作为枚举而不是类。
public enum Entity {

    A("a", "aExt"), B("b", "bExt"), C("c", "cExt");

    private final String name;
    private final String text;

    private Entity(String name, String text) {
        this.name = name;
        this.text = text;
    }

    public String getName() {
        return name;
    }

    public String getText() {
        return text;
    }

    public static Entity fromString(String raw) {

        return LOOKUP.get(raw);
    }

    private static final Map<String, Entity> LOOKUP = new HashMap<>();

    static {

        for (Entity e : values()) {
            LOOKUP.put(e.getName(), e);
        }
    }
}

并修改您的foo方法为

public ViewObject foo(String condition){

    /*
     *  pass condition as "a", "b", "c" only not "aRelated", "bRelated", "cRelated"
     * 
     */
    ViewObject vo = new ViewObject();
    Entity e = Entity.fromString(condition); 
    if(null != e) {
        vo.setValue1(e.getName());
        vo.setValue2(e.getText());
    }
    return vo;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接