Java programming test for interview

Here is a programming test used in a job interview. I find it has a very strange non-OO perspective and wonder why anyone would approach a constructor from this perspective. As a very experienced Java programmer, I immediately question the ability of the individual who wrote this code and the strange perspective of the question.

I find these strange out of context questions on interviews disturbing. I would love feedback from other experienced OO Java programmers.

Complete the Solver constructor so that a call to solveAll return a list with 2 values including the square root and the inverse of the integer passed as parameter.

public interface MathFunction {
    double calculate(double x);
}

public class Solver {

    private List<MathFunction> functionList;

    public Solver() { 

        //Complete here

    }

    public List<Double> solveAll(double x) {
        List<Double> result = new ArrayList<Double>();
        for (MathFunction function : this.functionList) {
            result.add(new Double(function.calculate(x)));
        }

        return result;
    }
} 

Solution 1:

This is testing your design patterns, by using the simplest possible method. I think this could be the Strategy (or some other behavioural pattern). See these:

http://en.wikipedia.org/wiki/Strategy_pattern

http://en.wikipedia.org/wiki/Behavioral_pattern

If you are going for a Java interview, you should be able to identify the design pattern they are hinting at and that should prevent you from being too unsettled!

To answer the question, create two classes that implement MathFunction as required, then create two instances and store them in functionList.

The point here is not 'can you do calculations in this strange way', it is 'can you identify design patterns'.

Solution 2:

I agree that it's confusing and over-engineered.

But I do think the code is reasonably object-oriented. It's an instance of the strategy pattern. The code that generates a list of answers doesn't care how the answers are calculated - the two concerns are separated and a different calculation strategy could be applied without having to touch the code that generates the list.

To make the class more useful, these functions should be passed in from the outside (i.e. dependency injection) rather than being instantiated in the constructor.

You know the answer, I assume, but for what it's worth...

public Solver() {
    functionList = new ArrayList<MathFunction>();

    functionList.add(new MathFunction() {

        @Override
        public double calculate(double x) {
            return 1d/x;
        }
    });

    functionList.add(new MathFunction() {

        @Override
        public double calculate(double x) {
            return Math.sqrt(x);
        }
    });
}

Solution 3:

IMHO, it is indeed a strange approach. The name Solver is generic, it shouldn't implement specific operations by default. However, maybe that was part of the interview? Part one: simply fulfill the request. Part two: say that it is strange to do so.

I would say that a much nicer approach would be to have an addMathFunction(MathFunction mf) method. And if wanted, to create subclasses that extend the Solver class and add MathFunctions in their constructor.

Solution 4:

I think they wanted you to add two items in the functionlist. Each one would implement the MathFunction interface, one for the square root and one for the inverse. The prboblem lies in the details:

1- You have a function which returns 2 values because it does two different things, that is bad

2- If you want to have this "do-it-all" class,m it would be interesting to receive the Mathfunctions as a parameter so you can do any sort of MathFunctions, the MathFunctions would be parameterizable