【发布时间】:2014-06-16 07:57:38
【问题描述】:
那里有一些 Matrix 库,每个库都有各自的优缺点 - 所以我决定现在我想使用一个通用界面,以便以后可以轻松地将一个库切换到另一个库。
我所拥有的是这样的:
public interface IMatrix {
public IMatrix add(IMatrix matrix);
public IMatrix multiply(IMatrix matrix);
...
}
在代码中:
IMatrix someMatrix = MatrixFactory.createDenseMatrix(3,5);
//I'm using a MatrixFactory to hide the different implementation constructors
例如,假设我想使用来自 EJML 和 La4j 的基类来实现这个 IMatrix。 我想到了两种解决方案,都不完美:
解决方案 1 - 在基类周围创建一个包装器:
这似乎可行,即使有点麻烦:
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));
}
思路二——扩展基类:
这似乎是个坏主意,因为类方法可能会被覆盖,而且无论如何它的方法会返回错误类型的对象 - 我不知道这是如何工作的。
class La4jDenseMatrix extends Basic2DMatrix implements IMatrixPar {
@Override
public IVector multiply(IMatrix matrix) {
return this.mult(matrix);
}
}
我认为解决方案 1 是做到这一点的唯一方法 - 还有其他更好的方法吗?
C++ 相关问题:Hiding multiple implementations behind a single interface
【问题讨论】:
-
我知道这纯粹是主观的,但请注意匈牙利符号是多余的,而且在 Java 中非常罕见(很少有明显的例外)。
-
你建议什么样的符号?
-
您应该使用
Matrix而不是IMatrix。这是常态:您会找到List、Map等,而不是IMap、IList... -
@Enoon 解决方案 1 还允许您一次使用多个实现类!想象一个不同的实现更好地处理不同矩阵大小的情况。根据构造函数参数,您实际上可以返回不同的实现来优化矩阵运算!
-
@StefanoSanfilippo 啊,是的。我称它为 IMatrix 是为了减少与 La4J 矩阵的混淆