我正在用Java编写代码,一个专门用于创建矩阵的代码,我使用了很多不同的方法。我试图将类似的方法分成单独的文件,因此它们更容易修改,但我没有办法在没有可怕的继承的情况下做到这一点。我正在尝试做什么,或者我应该咬紧牙关并将它们全部放在一个档案中? 例如,我有4个单独的文件。我能想到的唯一方法是不必导入许多不同的类:
MatrixBase - > MatrixSort - > MatrixMethods - >基质
我觉得一个类的继承是不必要的,当我想要做的就是在同一个文件中存储类似的方法。 什么是我最好的解决方案?
答案 0 :(得分:2)
Strategy
是允许将方法与对象分离的OOP设计模式之一。虽然它的主要目的是提供一种在运行时提供替代算法实现的机制,但您可能需要检查它是否适合您的情况。
答案 1 :(得分:1)
你不应该创造这么大的课程 - 这是一个非常糟糕的主意。
您需要开始评估如何将部分功能提取到其他小类中。其他类不需要向用户公开,如果你愿意,可以将它们打包为私有(如果你不提供访问级别,这就是你得到的)
您可以轻松拥有一个类似于" Matrix"的类,但这可以只是一个大量其他类的外观。
我不确定它是否与您正在做的事情相同但是我花了一段时间开发一个带有可替换数字实现的矩阵类,它可以处理特殊类型,如矩阵可以操作的有理和复杂类型
Java在这种工作中很悲惨(而且我可能是你遇到的最强大的java支持者,因此说的很多!)主要问题是数字类型没有一个有用的基础类型,但是做这种工作真的有助于能够超负荷运营商(我通常认为不仅仅是一种有吸引力的麻烦)
如果这是您正在处理的事情,我强烈建议您查看最高级别的groovy(使用类)。如果那不是你正在做的事情,那么抱怨咆哮,但你可能在此之前就已经停止了阅读:)
答案 2 :(得分:0)
如果单个类中的代码太多,则可能无法使用最佳的面向对象设计方法。此外,在Java中导入许多类也很好。但是,我会在你的问题范围内给你一个合理的选择。希望它有所帮助。
尝试使用合成以使功能在单个位置可用,同时仍然将它们逻辑分解为单独的类。 ...因此,我们假设您已将MatrixMath作为您的根类来访问所有矩阵操作。让我们假设你想要一个代数集合和一个排序集合。
// container that has all of your matrix math objects
public class MatrixMath {
MatrixMath(){};
public final MatrixAlgebra algebra = new MatrixAlgebra();
public final MatrixSort sort = new MatrixSort();
}
// put all of the algebra type functions here
public class MatrixAlgebra {
MatrixMultiply(){};
public static Matrix multiply(final Matrix a, final Matrix b) {
Matrix result;
// do something
return result;
}
}
// and your sorting functions here...
public class MatrixSort {
...
}
现在要访问矩阵乘法,你可以使用:
// create a reference to your MatrixMath class so that you
// can use your function.
public class Matrix {
final MatrixMath math = new MatrixMath();
Matrix times(Matrix other) {
return math.algebra.multiply(this,other);
}
}
如果你真的只是制作函数并且你将所有东西都设置为静态,那么你可以在任何地方使用静态引用。
答案 3 :(得分:0)
一种方法是使您的函数保持静态并将它们移动到静态实用程序类中。
所以而不是
Matrix m = ...;
Matrix mt = m.transpose();
float det = mt.determinant();
Vector x = ..;
Vector b = ..;
Vector y = m.solve(x,b);
你最终得到了
Matrix m = ...
Matrix mt = MatrixGeometry.transpose(m);
float det = MatrixMath.determinant(m);
Vector x = ..;
Vector b = ..;
Vector y = LinearAlgebra.solve(m,x,b);
有趣的部分是确定哪些函数应该保留成员函数,哪些函数应该是静态的。
如果你在Matrix
类型中使用继承,那么有一个缺点。如果你的heirachy看起来像这样,
static interface Matrix { ... }
class DenseMatrix implements Matrix { ... }
class SparseMatrix implements Matrix { ... }
class BandedMatrix implements Matrix { ... }
然后您可能最终会得到包含基于类型的调度的实现:
class LinearAlgebra {
public static Vector solve(Matrix m, Vector x, Vector b) {
if(m instanceof DenseMatrix)
return solveDense((DenseMatrix)m, x, b);
if(m instanceof SparseMatrix)
return solveSparse((SparseMatrix)m, x, b);
...
}
private solveSparse(SparseMatrix m, Vector x, Vector b) {
...
}
}
有多少人会考虑“代码味道”。您可以通过在Matrix类中使用双重调度/访问者样式来解决这个问题,但设置起来会有点麻烦 - 在许多情况下,实际上并不是那么可读/可维护。