How can I remove duplicated code between classes?

Maybe this is an option... but not the best i think.

public class SimpleRecursiveFibonacci {

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

protected BigInteger calculate(int n){
    return fibonacci(n - 2).add(fibonacci(n - 1)),
}

}

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

@Override
protected BigInteger calculate(int n) {
    if(!cache.containsKey(n)){
        BigInteger currentFibonacci = super.calculate(n);
        cache.put(n, currentFibonacci);
    }
    return cache.get(n)
}

}


Another example using Java 8 features - BiFunction interface with lambda expression:

BiFunction<Fibonacci, Integer, BigInteger> func = (fibonacci, n) -> {
    if (n < 2) {
        return BigInteger.ONE;
    }
    return fibonacci.calc(n - 2).add(fibonacci.calc(n - 1));
};

new CachedFibonacci(func).calc(100);

Implementation:

interface Fibonacci {
    BigInteger calc(int n);
}

class SimpleFibonacci implements Fibonacci {

    private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;

    SimpleFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
        this.fibonacci = fibonacci;
    }

    public BigInteger calc(int n) {
        return fibonacci.apply(this, n);
    }
}

class CachedFibonacci implements Fibonacci {

    private BiFunction<Fibonacci, Integer, BigInteger> fibonacci;
    private Map<Integer, BigInteger> cache = new HashMap<>();

    CachedFibonacci(BiFunction<Fibonacci, Integer, BigInteger> fibonacci) {
        this.fibonacci = fibonacci;
    }

    public BigInteger calc(int n) {
        if (!cache.containsKey(n)) {
            cache.put(n, fibonacci.apply(this, n));
        }
        return cache.get(n);
    }
}

How about something like this:

public class SimpleRecursiveFibonacci {

    /** Gets the fibonacci value for n */
    public final BigInteger fibonacci(int n) {
        if (n == 0) {
            return BigInteger.ZERO;
        } else if (n == 1) {
            return BigInteger.ONE;
        }
        return getFibonacci(n);
    }

    /** Recursively calculates the fibonacci by adding the two previous fibonacci. */
    protected final BigInteger calculateFibbonacci(int n) {
        return fibonacci(n - 2).add(fibonacci(n - 1));
    }

    /** 
     * Somehow get the fibonacci value for n.
     * Could be by calculation, getting it from a cache, or anything.
     * Defaults to calculation.
     */
    protected BigInteger getFibonacci(int n) {
        return calculateFibbonacci(n);
    }

}

public class MemoizedRecursiveFibonacci extends SimpleRecursiveFibonacci {

    // Cache using an array list as recommended by user @DodgyCodeException
    private ArrayList<BigInteger> cache = new ArrayList<>();

    @Override
    protected BigInteger getFibonacci(int n) {
        if (cache.size() < n) {
            BigInteger fib = calculateFibbonacci(n);
            cache.add(fib);
            return fib;
        } else {
            return cache.get(n - 1);
        }
    }
}

Tags:

Java

Dry