2016-10-15 2 views
0

Я должен очистить код Java, избавиться от множества вещей, но должен ли что-нибудь еще очистить, возможно, каким-то образом избавиться от нескольких операторов if, без полной перезаписи этот код? Не похоже, чтобы понять это, поскольку они настолько различны, чтобы складывать их в один «если». Есть идеи?Очистка 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; 
     } 
} 

ответ

4

Код, который вы написали, является чисто процедурным и в большинстве случаев считается плохой практикой при написании на объектно-ориентированном языке, таком как Java. Вы должны узнать о силе полиморфизма и не должны выполнить проверку типа вручную:

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

Вы должны думать о ваших сущностей домена (сотрудников) в качестве объектов и каждый конкретный сотрудник может определить свои собственные правила для расчета заработной платы ,

Давайте создадим абстрактный класс Employee с одним абстрактным методом int calculatePay(int h):

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

Слова абстрактный означает, что этот метод не имеет никакой фактической реализации, но вся логика для расчета заработной платы будет введена в подклассах Продавца, Кук и главный:

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)); 
    } 
} 

Это называется полиморфизм. Если этот термин является новым для вас, вы можете прочитать Oracle учебник в основы объектно-ориентированного программирования: https://docs.oracle.com/javase/tutorial/java/concepts/index.html

Мышление в Java книге Брюс Эккель также имеет хорошее объяснение основных понятий объектно-ориентированного программирования.

+0

Действительно хорошее объяснение ... –

+0

Это отличное объяснение, конечно! Это было написано моим учителем и, вероятно, должно было быть таким уродливым, как оно есть. У меня было ощущение, что ваш подход может быть достигнут каким-то образом, но я не мог этого сделать. Спасибо, что упростили мою учебную кривую! – Triinu86

0

java.util.Map сэкономить много, если/другое, и использовать 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; 
    } 

} 
-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"); 
     } 
    } 
+0

Возможно, вы не должны создавать карту для каждого экземпляра 'Calc8'. Кроме того, он не должен быть классом в первую очередь. – Clashsoft

+0

Возможно, зависит от варианта использования. Метод 'Calc8.() 'может оправдывать существование класса, поскольку он абстрагирует реализацию. –

+0

Что-то вроде этого было на самом деле моей первой идеей, почему бы не построить карту для каждого экземпляра Calc8? – Triinu86

Смежные вопросы