如何在没有工具的情况下删除类之间的重复代码?

时间:2018-10-31 19:48:05

标签: java dry code-reuse

我编写了函数的许多实现,以计算给定位置的斐波那契数。

斐波那契类:此类有助于我测试每个实现,而无需重写相同的测试代码。我不想在这里添加“ 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));
  }
}

和“记忆递归斐波那契”类

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类中有一些重复的代码

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

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

如何使其保持干燥?删除重复的代码?

2 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:1)

抽象的公共父母呢? 像这样:

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

这样,您的Fibonacci实现需要实现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));
    }
}