簡體   English   中英

清理java代碼,多個if語句

[英]Cleaning up java code, multiple if statements

我應該清理一個java代碼,擺脫很多東西,但是還有什么可以清理的,也許以某種方式擺脫多個if語句,而不完全重寫這段代碼? 似乎無法弄清楚,因為它們是如此不同,以至於無法將它們堆疊在一個“如果”中。 有任何想法嗎?

 public class Calc {
           // employee types
           public static final int SELLER;
           public static final int COOK;
           public static final int CHIEF;



       public static void main(final String[] args) {
              Calc c = new Calc();
              System.err.println(c.pay(CHIEF) + " should be 66");
       }

       private int pay(final int type, final int h) {
              int Sum = 0;
              if (type == SELLER) {
                     if (h > 8) { 
                           Sum = 20 * (h - 8);  
                           Sum += 80;
                     } else {
                           Sum += 10 * h;
                     }
              }
              if (type == COOK) {
                     if (h > 8) { 
                           Sum = 30 * (h - 8); 
                           Sum += 15 * 8;
                     } else {
                           Sum += 15 * h;
                     }
              }
              if (type == CHIEF) {
                     if (h > 8) { 
                           Sum = 66 * (h - 8); 
                           Sum += 22 * 8;
                     } else {
                           Sum += 22 * h;
                     }
              }
              if (h > 20) {
                     if (type == SELLER) {
                           Sum += 10;
                     }
                     if (type == COOK) {
                           Sum += 20;
                     }
                     if (type == CHIEF) {
                           Sum += 30;
                     }
              }
              return Sum;
       }
}

您編寫的代碼純粹是程序性的,在大多數情況下,在使用 Java 等面向對象語言編寫時被認為是一種不好的做法。 您應該了解多態的威力,而不應該手動執行類型檢查:

if (type == COOK) { //Avoid doing this in OO languages!

您應該將域實體(員工)視為對象,並且每種特定類型的員工都可以定義自己的計算工資的規則。

讓我們使用單個抽象方法int calculatePay(int h)創建一個抽象類 Employee :

public abstract class Employee {
    abstract int calculatePay(int h);
}

抽象一詞意味着該方法沒有實際實現,但所有計算工資的邏輯都將放在子類 Seller、Cook 和 Chief 中:

public class Cook extends Employee {

    public Cook() {}

    int calculatePay(int h) {
        int sum = (h > 20) ? 20 : 0;
        if (h > 8) {
            sum = 30 * (h - 8);
            sum += 15 * 8;
        } else {
            sum += 15 * h;
        }
        return sum;
    }
}

注意這一行:

    int sum = (h > 20) ? 20 : 0;

這是三元運算符 有時它適用於表達式中的條件賦值。 因此,當h大於 20 時,我們用 20 初始化sum變量,否則用 0 初始化。 現在我們不在我們的方法末尾使用額外的if語句。

現在每個員工都負責為自己計算工資,並且不需要在 PayCalculator 類中執行類型檢查 - 它在運行時根據參數類型動態解析要執行的代碼:

public class PayCalculator {

    int pay(Employee e, int hours) {
        return e.calculatePay(hours);
    }

    public static void main(String[] args) {
        Seller seller = new Seller();
        Cook cook = new Cook();
        Chief chief = new Chief();

        PayCalculator calc = new PayCalculator();

        System.out.println("Seller is payed " + calc.pay(seller, 15));
        System.out.println("Cook is payed " + calc.pay(cook, 10));
        System.out.println("Chief is payed " + calc.pay(chief, 22));
    }
}

這稱為多態性 如果您對這個術語不熟悉,您可以閱讀 OOP 基礎中的 Oracle 教程: https : //docs.oracle.com/javase/tutorial/java/concepts/index.html

Bruce Eckel 的Thinking in Java一書中也對基本的 OOP 概念有很好的解釋。

java.util.Map保存了很多 if/else,使用Enum作為用戶的選擇

public class X {

    public enum Type {
        SELLER, COOK, CHIEF
    }

    private Map<Type, Integer> constantValue1;
    private Map<Type, Integer> constantValue2;
    private Map<Type, Integer> additionalValue;

    public X() {
        initialConstantValue1();
        initialConstantValue2();
        initialAdditionalValue();
    }

    private void initialConstantValue1() {
        constantValue1 = new HashMap<>();
        constantValue1.put(Type.SELLER, 20);
        constantValue1.put(Type.COOK, 30);
        constantValue1.put(Type.CHIEF, 66);
    }

    private void initialConstantValue2() {
        constantValue2 = new HashMap<>();
        constantValue2.put(Type.SELLER, 10);
        constantValue2.put(Type.COOK, 15);
        constantValue2.put(Type.CHIEF, 22);
    }

    private void initialAdditionalValue() {
        additionalValue = new HashMap<>();
        additionalValue.put(Type.SELLER, 10);
        additionalValue.put(Type.COOK, 20);
        additionalValue.put(Type.CHIEF, 30);
    }

    int pay(final Type type, final int h) {
        int sum = 0;
        if (h > 8) {
            sum = constantValue1.get(type) * (h - 8);
            sum += constantValue2.get(type) * 8;
        }
        else {
            sum += constantValue2.get(type) * h;
        }
        if (h > 20) {
            sum += additionalValue.get(type);
        }
        return sum;
    }

}

這是在pay方法中使用最少的if語句清理或實現它的另一種方法。 將員工類型移動到enum ,然后每個enum類型都有自己的工資計算。 像這樣:

package sandbox;

public enum Employee {
    SELLER() {
        @Override 
        int pay(int h) {
            int sum = (h > 20) ? 10 : 0;
            if (h > 8) { 
                sum = 20 * (h - 8);  
                sum += 80;
            } else {
                sum += 10 * h;
            }
            
            return sum;
        }
    },
    COOK() {
        @Override 
        int pay(int h) {
            int sum = (h > 20) ? 20 : 0;
            if (h > 8) { 
                sum = 30 * (h - 8);  
                sum += 15 * 8;
            } else {
                sum += 15 * h;
            }
            
            return sum;
        }
    },
    CHIEF() {
        @Override 
        int pay(int h) {
            int sum = (h > 20) ? 30 : 0;
            if (h > 8) { 
                sum = 66 * (h - 8);  
                sum += 22 * 8;
            } else {
                sum += 22 * h;
            }
            
            return sum;
        }       
    };
    
    abstract int pay(int h);
}

而跑者...

package sandbox;

public class Main {

    public static void main(String[] args) {
        System.out.println(Employee.SELLER.pay(5));
        System.out.println(Employee.COOK.pay(5));
        System.out.println(Employee.CHIEF.pay(5));
    }
}

在 Java 8 中,該語言獲得了各種功能位,可用於功能性類型的清理。

    import java.util.EnumMap;
    import java.util.function.IntFunction;

    public class Calc8 {

        public enum Employee {
            SELLER, COOK, CHIEF;
        }

        private final EnumMap<Employee, IntFunction<Integer>> map = new EnumMap<>(Employee.class);

        public Calc8() {
            map.put(Employee.SELLER, h -> {
                int sum = h > 8 ? 20 * (h - 8) + 80 : 10 * h;
                return h > 20 ? sum + 10 : sum;
            });
            map.put(Employee.COOK, h -> {
                int sum = h > 8 ? 30 * (h - 8) + (15 * 8) : 15 * h;
                return h > 20 ? sum + 20 : sum;

            });
            map.put(Employee.CHIEF, h -> {
                int sum = h > 8 ? 66 * (h - 8) + (22 * 8) : 22 * h;
                return h > 20 ? sum + 30 : sum;
            });
        }

        public int evaluate(Employee e, int value) {
            return map.get(e).apply(3);
        }

        public static void main(final String[] args) {
            Calc8 c = new Calc8();
            System.err.println(c.evaluate(Employee.CHIEF, 3) + " should be 66");
        }
    }

為 pay 函數內部的類型編寫一個 switch 塊,而不是使用多個 if else 語句。 不要給出 type == SELLER ,而是創建一個適當的名稱並進行比較。

還有一個接口對員工有好處,使用工廠模式來獲取對象。

對於代碼清理,您還可以添加插件,如: https : //www.sonarlint.org/

暫無
暫無

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

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