Как я могу удалить дублированный код между классами без инструментов? - PullRequest
0 голосов
/ 31 октября 2018

Я написал много реализаций функции для вычисления числа Фибоначчи в заданной позиции.

Класс Фибоначчи : этот класс помогает мне тестировать каждую реализацию без перезаписи одного и того же тестового кода. Я не хочу добавлять «fibonacci(n - 2).add(fibonacci(n - 1));» здесь, потому что некоторые реализации не используют его (императивная итерация, функциональная итерация).

public interface Fibonacci {
  BigInteger fibonacci(int n);

}

Рекурсивный класс Фибоначчи

public class SimpleRecursiveFibonacci implements Fibonacci{

  public BigInteger fibonacci(int n) {
    if(n < 2) {
      return BigInteger.ONE;             
    }

    return fibonacci(n - 2).add(fibonacci(n - 1));
  }
}

и MemorizedRecursiveFibonacci Class

public class MemoizedRecursiveFibonacci implements Fibonacci{
  private Map<Integer, BigInteger> cache = new HashMap<>();

  public BigInteger fibonacci(int n) {
    if(n < 2) {
      return BigInteger.ONE;
    }
    if(!cache.containsKey(n)){
      BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));
      cache.put(n, currentFibonacci);
    }

    return cache.get(n);
  }
}

Как я вижу, в MemorizedRecursiveFibonacci Class есть некоторый дублированный код

 if(n < 2) {
      return BigInteger.ONE;

и

  BigInteger currentFibonacci = fibonacci(n - 2).add(fibonacci(n - 1));

Как я могу сохранить его СУХИМ удалить дублированный код?

Ответы [ 2 ]

0 голосов
/ 31 октября 2018

А как насчет абстрактного общего родителя? Примерно так:

public abstract class ParentFibonacci implements Fibonacci {
    protected BigInteger getFirstValues(int n) {
        if (n < 2) {
            return BigInteger.ONE;
        }
        return BigInteger.ZERO;
    }
}

Таким образом, ваша реализация Фибоначчи должна реализовывать Fibonacci.fibonacci (int n) и может использовать родительские методы.

public class SimpleRecursiveFibonacci extends ParentFibonacci {

    public BigInteger fibonacci(int n) {
        if (n < 2) {
            return getFirstValues();
        }
        return fibonacci(n - 2).add(fibonacci(n - 1));
    }
}
0 голосов
/ 31 октября 2018

MemorizedRecursiveFibonacci может делегировать RecursiveFibonacci экземпляр:

public class MemoizedRecursiveFibonacci implements Fibonacci {
  SimpleRecursiveFibonacci simple = new SimpleRecursiveFibonacci();
  private Map<Integer, BigInteger> cache = new HashMap<>();

  public BigInteger fibonacci(int n) {
    if(!cache.containsKey(n)) {
      BigInteger currentFibonacci = simple.fibonacci(n);
      cache.put(n, currentFibonacci);
    }

    return cache.get(n);
  }
}

Или, что еще более элегантно, с использованием Java 8 Map#computeIfAbsent:

public class MemoizedRecursiveFibonacci implements Fibonacci {
  SimpleRecursiveFibonacci simple = new SimpleRecursiveFibonacci();
  private Map<Integer, BigInteger> cache = new HashMap<>();

  public BigInteger fibonacci(int n) {
    return cache.computeIfAbsent(n, k -> simple.fibonacci(k));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...