Java - 将 Class 方法分离到不同的文件中

Java - Separating Class Methods into Different Files

我正在 Java 中编写代码,专门用于创建矩阵,我使用了许多不同的方法。我试图将类似的方法分离到单独的文件中,因此它们更容易修改,但如果没有可怕的继承,我无法想出一种方法来做到这一点。我正在尝试做的事情是可能的,还是我应该硬着头皮将它们全部放在一个文件中? 例如,我有 4 个单独的文件。我能想到的不需要导入许多不同 classes 的唯一方法是:

MatrixBase --> MatrixSort --> MatrixMethods --> Matrix

我觉得这种继承 class 是不必要的,因为我只想将类似的方法存储在同一个文件中。 我最好的解决方案是什么?

Strategy 是允许将方法与对象分开的 OOP 设计模式之一。虽然它的主要目的是提供一种在运行时提供替代算法实现的机制,但您可能需要检查它是否适合您的情况。

如果单个 class 中的代码过多,您可能没有使用最好的面向对象设计方法。此外,在 Java 中导入许多 classes 是可以的。但是,我会在你的问题范围内给你一个合理的选择。希望对你有帮助。

尝试使用组合以使函数在单个位置可用,同时仍然在逻辑上将它们分解为单独的 classes。 ...因此,假设您将 MatrixMath 作为根 class 来访问所有矩阵操作。假设您想要一组代数和一组排序。

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

如果您真的只是在创建函数并且将所有内容都设为静态,那么您可以在任何地方使用静态引用。

你不应该创建这么大的class——这是一个非常糟糕的主意。

您需要开始评估如何将部分功能提取到其他小型 classes 中。其他 classes 不需要向用户公开,如果您愿意,可以将它们打包为私有(如果您不提供访问级别,这就是您得到的结果)

您可以轻松地拥有一个 class,即 "Matrix",但这可能只是大量其他 class 的外观。

我不确定这是否与您正在做的事情相同,但我花了一段时间开发了一个矩阵 class,它具有可替换的数字实现,适用于特殊类型,如有理数和复杂类型矩阵可以操纵。

Java 对这种工作很痛苦(而且我可能是你们 运行 最坚定的 java 支持者,所以说得太多了!)主要问题是数字类型没有有用的基类型,但要完成这种工作,能够重载运算符确实很有帮助(我通常认为这只是一种有吸引力的麻烦)

如果这是您正在从事的工作,我强烈建议您查看 groovy 的最顶层(使用 classes)。如果这不是你正在做的事情,那么对你的咆哮感到抱歉,但你可能已经停止阅读这里了:)

一种方法是使您的函数静态化并将它们移动到静态实用程序中 classes。

所以

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 类型中使用继承,则有一个缺点。如果你的继承人是这样的,

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) {
     ...
   }
}

很多人会考虑 "code smell"。您可以通过在您的 Matrix class 中使用双重调度/访问者样式来解决这个问题,但是设置起来会更痛苦一些 - 在许多情况下并没有那么多 readable/maintainable。