【问题标题】:Is it bad to have private static fields in Util classes?在 Util 类中有私有静态字段是不是很糟糕?
【发布时间】:2019-09-25 13:08:54
【问题描述】:

假设我在一个 util 类中有一个方法,该方法有一个不能在方法中更改的参数,因为它会改变结果并且需要以某种方式保存,如果这样做是一个不好的做法吗? util 类中的private static 字段?如果是的话如何正确地做到这一点。

我的意思是这样的:

public class Util {

    private static final int[] vector1Backup = new int[3];
    private static final int[] vector2Backup = new int[3];

    private Util() {
    }

    public static void doOperation(int[] vector1, int[] vector2, int[] result){

        // backups needed for the case that vecto1 or vector2 = result
        vector1Backup[0] = vector1[0];
        vector1Backup[1] = vector1[1];
        vector1Backup[2] = vector1[2];

        vector2Backup[0] = vector2[0];
        vector2Backup[1] = vector2[1];
        vector2Backup[2] = vector2[2];

        result[0] = vector1Backup[0] + vector2Backup[2];
        result[1] = vector1Backup[1] + vector2Backup[1];
        result[2] = vector1Backup[2] + vector2Backup[0];
    }

}

编辑:只存在一个线程

【问题讨论】:

  • 如果两个线程同时调用doOperation方法会发生什么?
  • @KevinO 我认为更好的问题是,不会发生什么? :P
  • 是的,这很糟糕。实用程序类不应该保持状态。在单个方法中处理所有内容或构建一个 calculator 对象,您可以在其中进行仅用于单一用途的计算(创建对象、进行计算、销毁对象)。
  • 您不修改的私有静态 final 字段很好。私有静态可变字段是主要的代码异味。
  • 只要它的单线程和你的字段用作计算的临时结构,我看不出有什么问题。还有其他库以相同的方式工作。例如 LibGDX。它使用临时向量和矩阵来计算事物以防止过多的实例化。

标签: java access-modifiers


【解决方案1】:

一般来说,拥有私有常量并不是一个坏习惯。隐藏类的内部是很好的,在 OOP 中我们称之为封装。但是我觉得你的代码应该稍微改变一下。

1) 就我个人而言,我完全反对静态方法,恕我直言,它们不遵循 OOP 并且使测试更加困难。然而,一堆库和 java 本身就有一堆。所以这是品味问题,我猜。如果你喜欢静态方法,你应该做无状态的,这意味着不要在类中存储任何东西,只需根据vector1和vector2创建结果并从方法中返回。

2) 在静态类中存储一些东西很容易出错。我只会创建单独的类并将其称为 VectorBackup。在那个类中,我会像你一样存储向量。然后您可以创建所需的任意数量的实例(备份)。这将是线程安全的(在一定程度上)并且更像 OOP。此外,如果您有 3 个向量而不是 2 个向量,更改代码会更容易。

3) 常量类应该有私有构造函数,并且应该是final,所以没有人可以扩展它们。

public final class Util {

    private Util() {
    }

    public static void doOperation(int[] vector1, int[] vector2) {
        int[] result = new int[3];
        result[0] = vector1[0] + vector2[2];
        result[1] = vector1[1] + vector2[1];
        result[2] = vector1[2] + vector2[0];
        return result;
    }

}


public class Backup {

    private final int[] vectorBackup = new int[3];

    public Backup(int[] vector) {
        vectorBackup[0] = vector[0];
        vectorBackup[1] = vector[1];
        vectorBackup[2] = vector[2];
    }

    public int[] restore(){
     //some code to create vector from backup
    }

}

【讨论】:

    【解决方案2】:

    拥有私有常量并不是一个坏习惯。

    但是在您的情况下,您有一个私有字段,例如缓冲区。加上你进行所谓的就地操作,改变result数组的值。

    如果我是你,我会创建一个返回结果的函数

    int[] doOperation(int[] vector1, int[] vector2){
      int[] result = new int[vector1.length];
      // do your logic
      return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2013-04-17
      • 1970-01-01
      • 2010-12-16
      • 2011-06-17
      • 2015-10-29
      • 1970-01-01
      • 1970-01-01
      • 2011-05-23
      • 1970-01-01
      相关资源
      最近更新 更多