[英]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.