正确的折射if语句的方法

时间:2019-02-06 20:13:03

标签: java android if-statement refactoring

我想知道这是否是重构多个if语句的好方法?我听到的是if语句是“不好的”做法,我想通过重构一些代码将程序提高到一个新的水平。

原始代码:

public int Colors(String col, int row){
    int ret = 0;
    if(col.equals("R")){
        ret = Color.parseColor("#EF5350");
    }else if(col.equals("B")) {
        ret = Color.parseColor("#7986CB");
    }else if(col.equals("V")){
        ret = Color.WHITE;
    }else if(col.equals("G")){
     ret = Color.parseColor("#FFE082");
    }else if(Math.floorMod(row,2) == 0){
        ret = Color.parseColor("#e0e0e0");
    }else{
         ret = Color.parseColor("#eeeeee");
    }

返回ret;     }

新代码:

public int Colors(String col, int row){

    Map<String,Integer> ColorMap1 = new HashMap<>();

    ColorMap1.put("R", Color.parseColor("#EF5350"));
    ColorMap1.put("B",Color.parseColor("#7986CB"));
    ColorMap1.put("V",Color.parseColor("#FFE082"));
    ColorMap1.put("G",Color.parseColor("#FFFFFF"));

    Integer current = ColorMap1.get(col);

    Map<Integer,Integer> ColorMap2 = new HashMap<>();

    ColorMap2.put(0,Color.parseColor("#e0e0e0"));
    ColorMap2.put(1,Color.parseColor("#eeeeee"));

    Integer current2 = ColorMap2.get(Math.floorMod(row,2));

    return  current != null ? current  : current2 ;

}

5 个答案:

答案 0 :(得分:0)

If语句并不是天生就糟糕的。对于较大的比较块,它们可能有些笨拙,但是在Java中,没有通用的替代方法。 (您可以在Kotlin中使用when。)

由于那里有一个很大的块,并且您正在比较字符串,因此对于大多数情况,您始终可以使用switch语句:

public int colors(String col, int row) //method names in Java should usually use camelCase, not TitleCase
    switch(col) {
        case "R":
            return Color.parseColor("#EF5350");
        case "B":
            return Color.parseColor("#7986CB");
        case "V":
            return Color.WHITE;
        case "G":
            return Color.parseColor("#FFE082");
        default: //comparable to an "else" statement
            if (Math.floorMod(row, 2) == 0) return Color.parseColor("#e0e0e0");
            else return Color.parseColor("#eeeeee");
    }
}

答案 1 :(得分:0)

if通常不是不好的做法。只是当您发现自己连续使用多个链接的if-else if块时,通常是代码气味表明您可以更有效地执行工作。

在这种情况下,使用静态Map是重构大部分代码的一种好方法,以使其比等效的if更有效。问题在于,因为其中一个条件与其余条件不匹配,并且它不是恒定值。因此,您可以像这样部分重构代码:

static HashMap<String, Color> colorMap;

static {
    colorMap = new HashMap<>();
    colorMap.put("R",Color.parseColor("#EF5350"));
    colorMap.put("B",Color.parseColor("#7986CB"));
    colorMap.put("V",Color.parseColor("#FFE082"));
    colorMap.put("G",Color.parseColor("#FFFFFF"));
}

// ...

public int Colors(String col, int row) {
    if (colorMap.containsKey(col)) {
      return colorMap.get(col);
    }

    if (Math.floorMod(row, 2) == 0) {
      return Color.parseColor("#e0e0e0");
    }

    return Color.parseColor("#eeeeee");
}

或者,您可以使用switch块来完成类似的操作:

public int Colors(String col, int row) {
    switch (col) {
        case "R": return Color.parseColor("#EF5350");
        case "B": return Color.parseColor("#7986CB");
        case "V": return Color.parseColor("#FFE082");
        case "G": return Color.parseColor("#FFFFFF");
    }

    if (Math.floorMod(row, 2) == 0) {
      return Color.parseColor("#e0e0e0");
    }

    return Color.parseColor("#eeeeee");
}

答案 2 :(得分:0)

if-statementsswitch-statements总是不好的说法。有时它们导致更简洁的代码。但是,如果案件数量确实增加,那么使用Map会变得更加干净。

您可以将地图注册表用于颜色,如下所示:

public class SomeClass {
    private static int DEFAULT_COLOR = Color.parseColor("#eeeeee");
    private static Map<ColorKey, Integer> COLORS = new HashMap<>();
    static {
        COLORS.put(ColorKey.of("R", null), Color.parseColor("#EF5350"));
        COLORS.put(ColorKey.of("B", null), Color.parseColor("#7986CB"));
        COLORS.put(ColorKey.of("V", null), Color.WHITE);
        COLORS.put(ColorKey.of("G", null), Color.parseColor("#FFE082"));
        COLORS.put(ColorKey.of(null, 0), Color.parseColor("#e0e0e0"));
    }

    public Integer colors(String col, int row) {
        return COLORS.getOrDefault(ColorKey.of(col, row), DEFAULT_COLOR);
    }

    private static final class ColorKey {
       private final String col;
       private final Integer row;
       private ColorKey(String col, Integer row) {
           this.col = col; this.row = row;
       }
       private static ColorKey of(String col, Integer row) {
           return new ColorKey(key(col), key(row));
       }
       private static String key(String col) {
           Set<String> columns = new HashSet<>(Arrays.asList("R", "B", "V", "G"));
           return columns.contains(col) ? col : null;
       }
       private static Integer key(Integer row) {
           return row != null && Math.floorMod(row,2) == 0 ? Integer.valueOf(0) : null;
       }
       @Override
       public boolean equals(Object obj) {
           if (obj == null) return false;
           if (obj == this)  return true;
           if (!(obj instanceof ColorKey)) return false;
           ColorKey that = (ColorKey) obj;
           return Objects.equals(this.col, that.col) && Objects.equals(this.row, that.row);
       }
       @Override
       public int hashCode() {
           int result = 17;
           result = 31 * result + Objects.hash(col);
           result = 31 * result + Objects.hash(row);
           return result;
       }
    }
}

答案 3 :(得分:0)

如果在不同的地方过度使用

If语句,则是不好的做法。 重构的最佳方法是使用设计模式 有很多模式可以代替if语句使用,例如strategystatecommand模式

答案 4 :(得分:0)

您可以使用enum添加不同的颜色:

public class Main
{
    public static void main(String[] args) {
        String colorName = "R";
        int row = 23;
        System.out.println("Color code: " + ColorSchema.getColor(colorName, row).getCode());
    }
}


enum ColorSchema {

  R("#EF5350"), 
  B("#7986CB"), 
  V("#FFE082"),
  G("#FFFFFF"),

  ROW0("#e0e0e0"),
  ROW1("#eeeeee");

  private String color;

  ColorSchema(String color) {this.color = color;}
  public int getCode(){ return Color.parseColor(color);}

  public static ColorSchema getColor(String name, int row) {
    for (ColorSchema c : ColorSchema.values()) {
      if (c.color.equals(name)) {
        return c;
      }
    }
    return ColorSchema.valueOf("ROW" + Math.floorMod(row, 2));
  }

}