我应该清理一个java代码,摆脱了很多东西,但应该还有什么可以清理,也许以某种方式摆脱多个if语句,而不完全重写这段代码?似乎无法弄清楚它们是如此不同,以便将它们堆叠在一个'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;
}
}
答案 0 :(得分:5)
您编写的代码纯粹是程序性的,在大多数情况下,在使用Java等面向对象语言编写时,这被认为是一种不好的做法。您应该了解多态性的强大功能,不应手动执行类型检查:
if (type == COOK) { //Avoid doing this in OO languages!
您应该将您的域实体(员工)视为对象,并且每种特定类型的员工都可以定义自己的计算薪酬的规则。
让我们用一个抽象方法int calculatePay(int h)
:
public abstract class Employee {
abstract int calculatePay(int h);
}
Word abstract 意味着此方法没有实际实现,但所有计算薪酬的逻辑都将放在卖家,库克和酋长的子类中:
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;
这是三元运算符。有时它对表达式中的条件赋值很有用。因此,当sum
大于20时,我们将h
变量初始化为20,否则为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
Java思考本书由Bruce Eckel对基本的OOP概念进行了很好的解释。答案 1 :(得分:0)
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;
}
}
答案 2 :(得分:0)
这是在 if
方法中使用最少的 pay
语句清理或实现它的另一种方法。将员工类型移动到 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));
}
}
答案 3 :(得分:-1)
使用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");
}
}
答案 4 :(得分:-1)
为pay函数内部的类型写一个switch块,而不是使用多个if else语句。 与其提供 type == SELLER ,不如创建一个适当的名称并进行比较。
还有一个接口对员工很有好处,有一个工厂模式来获取对象。
对于代码清理,您还可以添加插件,例如: https://www.sonarlint.org/