清理java代码,多个if语句

时间:2016-10-15 20:52:54

标签: java code-cleanup

我应该清理一个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;
       }
}

5 个答案:

答案 0 :(得分:5)

您编写的代码纯粹是程序性的,在大多数情况下,在使用Java等面向对象语言编写时,这被认为是一种不好的做法。您应该了解多态性的强大功能,不应手动执行类型检查:

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

您应该将您的域实体(员工)视为对象,并且每种特定类型的员工都可以定义自己的计算薪酬的规则。

让我们用一个抽象方法int calculatePay(int h)

创建一个抽象类Employee
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/