views:

63

answers:

3

Since a few years, common sense seems to dictate that it's better to program against interfaces rather than against implementations. For high-level code this indeed seems logical, e.g. if I have a complex solver in my application, it seems better to have something like this:

ISolver *solver = solverFactory.getSolver();
solver->solve(inputdata);

Rather than

Solver solver;
solver.solve(inputdata);

In the first code it is also easier to mock the solver, and thus, to unit test.

But my question is: at which level doesn't it make sense anymore to use interface. E.g. if I have a ComplexNumber class (or String class, or whatever) in my application, then writing this:

IComplexNumber *complexNumber = complexNumberFactory.create(1,2);   // 1+2i

Seems much more complex (especially regarding performance) than writing:

ComplexNumber complexNumber(1,2);   // 1+2i

So, which elements are important in deciding whether something should be put behind an interface and when it shouldn't be put behind an interface?

+2  A: 

Reasons to move to an interface are when it makes things simpler or reduces coupling. (Thats what an interface is for).

Reasons to move away from an interface are if it makes things more complicated or kills performance (but profile that to be sure). I'd argue that your IComplexNumber class actually makes the class heirarchy more complex unless you're introducing a MockComplexNumber, but I doubt such a class would be usefull... and it will probably make make things slower, but I'd measure that.

But don't think you need to do everything one way, or that your decisions are fixed in stone. It's pretty easy to convert to/from using an interface.

Michael Anderson
A: 

With C++ it does not matter so as c++ has multiple inheritance and so an interface is an abstract class which you can add implemetation to. Where I have found interfaces most used is Java and C# which have single inheritance and if you wan a class to implement several things only one can be an abstract class the others must be interfaces

Mark
+1  A: 

If you divide your classes into "service" and "value" classes, depending on the roles they play, then the answer is simple. Only use interfaces on service classes. In your question, "solver" is a service and "complex number" is a value.

Value classes should be easy to create using new() because they only accept basic types and other value classes in the constructor. Value classes are not useful to mock because you can use the real thing.

It may be useful to mock service classes and you may want multiple implementations. Your solverFactory could return a naiveSolver, a lookupSolver, a geneticSolver, a mockSolver etc. Here an interface is uesful.

WW