【问题标题】:Java - Separating Class Methods into Different FilesJava - 将类方法分离到不同的文件中
【发布时间】:2015-05-13 23:20:01
【问题描述】:

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

MatrixBase --> MatrixSort --> MatrixMethods --> 矩阵

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

【问题讨论】:

  • 如果方法在不同的文件中会更容易吗?从我的角度来看,方法应该在它们所属的逻辑域中定义(属于矩阵的方法应该在那里定义)。如果您确定不会将逻辑对象分解成碎片,请将另一个类中的方法定义为静态方法。
  • 主要是为了减少一个文件中的大量代码。

标签: java inheritance methods


【解决方案1】:

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

【讨论】:

  • 谢谢,我去看看。
【解决方案2】:

如果单个类中有太多代码,您可能不会使用最佳的面向对象设计方法。此外,在 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】:

你不应该创建这么大的类——这真是个坏主意。

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

您可以轻松地拥有一个“矩阵”类,但它可以只是大量其他类的外观。

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

Java 在这种工作上很糟糕(而且我可能是你会遇到的最强大的 Java 支持者,所以这说得太多了!)主要问题是数字类型没有有用的基类型,但要完成这种工作,重载运算符确实很有帮助(我通常认为这只是一种有吸引力的麻烦)

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

【讨论】:

  • 是的,我同意。这不是一个真正的大类,我只是喜欢简化。它最初是用 python 编写的,但我正在努力改进我的 java,所以我将一些旧程序放入 java。缺少运算符重载是我确实注意到的一件事,并且很惊讶 java 没有,尽管这实际上只是意味着它看起来不像在允许它的语言中那样漂亮。我的矩阵不复杂或不合理,只是 int、float、double 和 long。我已经掌握了逻辑,它只是结构和语法。谢谢你的建议! (顺便说一句,我读了人们对我说的一切:))
【解决方案4】:

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

所以不是

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

许多人会认为是“代码异味”。您可以通过在 Matrix 类中使用双重调度/访问者样式来解决此问题,但设置起来有点麻烦 - 而且在许多情况下,可读性/可维护性并不高。

【讨论】:

  • 这是个好主意,我可能会这样做。我会看看它的样子。
猜你喜欢
  • 1970-01-01
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 2011-08-11
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 1970-01-01
相关资源
最近更新 更多