Java 处理大班

Java 处理大班,java,class,matrix,cohesion,Java,Class,Matrix,Cohesion,在过去的几个月里,我最近开始用Java编写代码。我有一个矩阵类,它的方法太多了。我还有一个SquareMatrix类,它扩展了矩阵,并减少了一些膨胀 我发现Matrix类中的很多方法通常与矩阵相关。它有所有的基础,如addMatrix(矩阵)、multilyMatrix(矩阵)、multilyMatrix(浮点),然后是更复杂的方法,如getGaussian(矩阵)或getLUDecomposition(矩阵) 在减少类矩阵中的行数方面,我有哪些选择? 一个类变得非常大是正常的吗?我不这么认为。

在过去的几个月里,我最近开始用Java编写代码。我有一个矩阵类,它的方法太多了。我还有一个SquareMatrix类,它扩展了矩阵,并减少了一些膨胀

我发现Matrix类中的很多方法通常与矩阵相关。它有所有的基础,如addMatrix(矩阵)、multilyMatrix(矩阵)、multilyMatrix(浮点),然后是更复杂的方法,如getGaussian(矩阵)或getLUDecomposition(矩阵)

在减少类矩阵中的行数方面,我有哪些选择? 一个类变得非常大是正常的吗?我不这么认为。。。 这是不是我早就应该考虑的问题,重构很困难?还是有简单的解决方案

谢谢大家!


编辑:在阅读了一些回复后,我正在考虑做以下工作:

实用程序类矩阵包含矩阵的所有常用/基本方法

委派类(助手/子):

*助手类* getGaussian(..),getLUFactorization(..,)

子类 (扩展矩阵) 平方矩阵,下三矩阵,上三矩阵

委托类似于用C++中的头定义多个.CPP文件。 欢迎提供更多提示


Edit2:另外,我更喜欢通过正确的设计进行重构,而不是快速修复。我希望它对未来的项目有所帮助,而不仅仅是这个项目。

接口应该是完整的和最小的,这意味着类型接口应该包含在该类型上实现所需和有意义的任务所必需的所有方法,并且只包含这些方法

因此,分析Matrix的API方法并确定其中哪些属于核心API(必须能够访问类的内部以完成其任务),哪些提供“扩展”功能。然后将类API简化为核心功能,将其余的方法迁移到单独的helper/utility/子类,这些子类可以使用公共核心API实现它们的目标

对于重构/单元测试有帮助,请考虑米迦勒Fuels.

p>什么是“非常大”?


我认为该方法不应该超过100行,类不应该超过1000行,包括javadoc。如果您需要更多,请检查您的设计。使用委托,即将逻辑划分为模块/类,并从一个类调用另一个类

重构肯定是一件好事,但要可靠地重构是很困难的,除非你有好的单元测试。提供了一种实现通常易于重构的代码库的方法

对于没有单元测试的现有代码,这意味着在需要首先隔离要重构的区域之前,先编写单元测试,然后重构。如果这仅仅是一个个人项目,那么您可能只需要为您希望在重构过程中完好无损地生存下来的一组最小的特性编写测试就可以了

关于如何进行手头上的重构,有几个原则和方法,正如其他一些答案所指出的那样。在大多数情况下,对我起作用的是:

严格执行以下样式规则:
  • 方法的长度不能超过40行
  • 不能超过20
  • 还有其他的,但我个人发现这些对引导我远离糟糕的设计非常有帮助。限制方法长度迫使您真正考虑方法签名并编写简洁、集中的方法。这通常使复制更容易发现和删除。限制类扇出在类级别也有类似的效果,它迫使您认真思考类的角色,并使其简洁

    诸如之类的工具可以强制执行这两项,以及一系列其他样式规则

    和都提供了一个“提取方法”重构,这使得它只需突出显示要提取的代码并点击快捷键即可。IntelliJ甚至会检查类中是否出现完全相同的代码,并用对新方法的调用来替换它们。事实上,我建议在手动复制、粘贴和编辑的过程中始终使用此类重构工具。

    快速而肮脏的方法可以让臃肿的类看起来干净(将混乱的部分移到别处)

    您可以将方法的内容放在外部实用程序类的静态方法中

    例如:

    Matrix.java

    import MatrixUtils;
    //[...]
    public class Matrix
    {
        //[...]
        Matrix()
        {
            //[...]
        }
        //[...]
        public Gaussian getGaussian(Matrix m)
        {
            return MatrixUtils.computeGaussian(m);
        }
        public LUDecomposition getLUDecomposition(Matrix m)
        {
            return MatrixUtils.computeLUDecomposition(m);
        }
    }
    
    MatrixUtils.java

    protected class MatrixUtils
    {
        private MatrixUtils()//Utility class: prevent instantiation
        {//nothing
        }
        //[...]
        protected static Gaussian computeGaussian(Matrix m)
        {
            //do your superlong 100+lines Algorithm and return the result
        }
        public static LUDecomposition computeLUDecomposition(Matrix m)
        {
            //do your superlong 100+lines Algorithm and return the result
        }
    }
    
    通过这种方式(如我所说,快速而肮脏的),您可以清晰地浏览您的矩阵类(特别是当您有很多方法和javadoc时)

    当您想要访问实际的代码时,可以转到MatrixUtils

    如果出于某种原因,每个方法都非常长(200多行代码!),如果出于其他原因,您真的需要保持.java文件的简短,那么您甚至可以为每个[uber long]方法创建一个“静态类”(即仅包含静态方法的实用程序类)


    …当然,在任何情况下,您都应该在某种程度上进行@oksayt提到的“过程”重构,即通过将一些代码块放入单独(但一致)的函数中来缩短方法。

    对于基本矩阵运算,您可以使用具有适当许可证的开源实现。你可以考虑:-

    这肯定会减少您的总体代码大小,并从更多经过测试和使用的代码库中获益


    希望这能有所帮助。

    从中阅读有关反模式的内容。希望对您有所帮助…我读了一些关于委派的内容,这肯定是我将要开始实施的内容。+1用于提及扇出。然而,我要在(1)条规则中添加一条注释:如果你是一个“单独”的程序员(并且没有人需要访问你的代码),你可以有方法,只要它们完全适合你的屏幕。例如,如果您总是使用大型监视器,则可以在重构之前设置最大限制