繁体   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