2015-05-19 4 views
1

Мне была предоставлена ​​обратная связь, что мне нужно улучшить мои навыки рефакторинга/эмулирования кода.Код рефакторинга Java smells

  1. мне нужно короткие упражнения, чтобы обнаружить и как-улучшить самый Comon код запахов с ответами в Java

  2. пример:

    public class Calculator { 
    
        public long sum(int min, int max) { 
         long result = 0; 
         for (int i = min ; i <= max ; i++) 
          result += i; 
         return result; 
        } 
    
        public long sumOfSquares(int min, int max) { 
         long result = 0; 
         for (int i = min ; i <= max ; i++) 
          result += i * i; 
         return result; 
        } 
    
    } 
    

, а затем лучшее/самое удобное решение. BTW, вы могли бы сразу показать мне лучшее решение для этого повторения там/\ возможно с использованием оператора лямбда "->"

Спасибо!

+0

начала разделительным общего и не общего кода. – Stultuske

+1

BTW '->' не * альфа *, но * lambda * :) – Pshemo

+0

Конечно, это действительно так, но повторение просто болит глазами, оба метода почти одинаковы. – Filip

ответ

2

Вы можете попробовать слияние оба метода в одном. Так как они выглядят, как

public long sum(long min, long max) { 
    long result = 0; 
    for (int i = min ; i <= max ; i++) 
     result += someOperation(i); 
    return result; 
} 

вы могли бы позволить пользователю обеспечить некоторую операцию, которая будет вычислять i, поэтому он может быть i или i+2 или i*i.

Такая стратегия может быть реализована в интерфейсе LongUnaryOperator, где пользователю необходимо реализовать метод long applyAsLong(long operand).

Таким образом, вместо двух методов, которые вы можете иметь один, который может выглядеть как

public static long sum(long min, long max, LongUnaryOperator mapper) { 
    long result = 0; 
    for (long i = min ; i <= max ; i++) 
     result += mapper.applyAsLong(i); 
    return result; 
} 

, и вы можете использовать его как

sum(1, 4, i -> i * i)//sum of squares 

i->i*i является лямбда-выражение, которое реализует функциональный интерфейс LongUnaryOperator и обеспечивает реализацию его абстрактного метода applyAsLong, который будет использоваться в нашем коде. Другими словами, он будет отображать i по адресу: i*i.

больше примеров использования:

sum(1, 4, i -> 2 * i)//sum of doubled values 
sum(1, 4, i -> i)//sum of original values 
//i->i can be also returned with `LongUnaryOperator.identity()` 
//so you can rewrite your code into something like 
sum(1, 4, LongUnaryOperator.identity()) 

Вы также можете переписать свой код, используя потоки как

public static long sum(long min, long max, LongUnaryOperator mapper) { 
    return LongStream.rangeClosed(min, max).map(mapper).sum(); 
} 
Смежные вопросы