Enoon
Enoon

Reputation: 421

Hide multiple (given) implementations behind an interface

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:

Solution 1 - creating a wrapper around the base class:

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

Idea 2 - extending the base class:

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

Answers (1)

CDahn
CDahn

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

Related Questions