簡體   English   中英

正確的折射if語句的方法

[英]Correct way to refractor if-statements

我想知道這是否是重構多個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 ;

}

If語句並不是天生就糟糕的。 對於較大的比較塊,它們可能有些笨拙,但是在Java中,沒有通用的替代方法。 (你可以使用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");
    }
}

if一般來說是不錯的做法。 只是當您發現自己使用多個鏈式ifelse 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塊完成類似的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");
}

有爭議的是, 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;
       }
    }
}

If在不同的地方使用了過多的if語句,則是不好的做法。 重構的最佳方法是使用設計模式可以使用許多模式來代替if語句,例如strategystatecommand模式

您可以使用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));
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM