Reputation: 421
There are a few Matrix libraries out there, each with their goods and bads - so i decided that for now i'd like to use a common interface so that i can easily switch one library for another later on.
What i have is something like:
public interface IMatrix {
public IMatrix add(IMatrix matrix);
public IMatrix multiply(IMatrix matrix);
...
}
And in the code:
IMatrix someMatrix = MatrixFactory.createDenseMatrix(3,5);
//I'm using a MatrixFactory to hide the different implementation constructors
As an example, say i want to implement this IMatrix using the base classes from EJML and La4j. I thought of two solutions, none perfect:
This seems to work, even if a little cumbersome:
class SimpleMatrixInside implements IMatrix{
private final SimpleMatrix matrix;
SimpleMatrixInside(SimpleMatrix m) {
matrix = m;
}
@Override
public IMatrix add(IMatrix someMatrix) {
SimpleMatrixInside toSum = (SimpleMatrixInside)someMatrix;
return new SimpleMatrixInside(matrix.plus(toSum.matrix));
}
@Override
public void set(int row, int col, double val) {
this.matrix.set(row,col, val);
}
@Override
public IMatrix multiply(IMatrix matrix) {
SimpleMatrix toMultiply= ((SimpleMatrixInside)matrix).matrix;
return new SimpleMatrixInside(this.matrix.mult(toMultiply));
}
This seems like a bad idea since class methods could be overridden and anyway its methods would return the wrong type of object - i don't know how this could work.
class La4jDenseMatrix extends Basic2DMatrix implements IMatrixPar {
@Override
public IVector multiply(IMatrix matrix) {
return this.mult(matrix);
}
}
I think Solution 1 is the only way to do this - are there other, better ways?
Related question for C++: Hiding multiple implementations behind a single interface
Upvotes: 0
Views: 522
Reputation: 1876
Yes, solution 1 is the right way to go. This has the distinct advantage of giving you the control of how to map each implementation class' API to IMatrix.
Imagine two different APIs that have similar functionality, but different method calls. The only way to normalize this is exactly what you propose in suggestion 1.
Upvotes: 2