【发布时间】:2018-02-19 05:16:48
【问题描述】:
在 Robert C. Martin 的《清理代码》一书中,他清理了一个杂乱无章的类,并以这种方式以一个由静态变量和静态函数组成的文件结束。
public class PrimeGenerator{
private static int[] primes;
private static ArrayList<Integer> multipleOfPrimes;
public static int[] generate(int n){
primes = new int[n];
//call functions
someFunctionThatModifiesPrimes()
return primes;
}
private static void someFunctionThatModifiesPrimes(){
//modify primes
prime[x] = y;
}
}
他写
请注意,它并不是要被实例化为对象。班上 只是一个有用的作用域,可以在其中声明和隐藏变量。
我的问题是,当我能做到这一点时,我为什么还要去做他所做的事情:
public class PrimeGenerator{
private int[] primes;
private ArrayList<Integer> multipleOfPrimes;
public PrimeGenerator(int n){
primes = new int[n];
}
public int[] generate(int n){
//call functions
someFunctionThatModifiesPrimes()
return primes;
}
private void someFunctionThatModifiesPrimes(){
//modify primes
prime[x] = y;
}
}
他的代码:
a) 不是线程安全的,在素数已经生成(从多个线程调用)时调用“generate(int)”会导致失败。
b) 在完成运行后保留一个带有垃圾素数的全局变量,它只会在下次运行时被覆盖。
我能想到的唯一优点是它可能更快?即便如此,这也可以忽略不计。
需要创建对象的代码是线程安全的,不会保留垃圾数据并且没有静态状态。
【问题讨论】:
-
是的,缺乏线程安全是 Martin 的 Clean Code 中的一个常见主题。可能是这本书年代久远的结果。人们过去不关心这些东西(即使在当时也是愚蠢的,并导致遗留代码库中的许多问题)。
-
@CodyGray 即使不考虑线程安全,我也很难理解这种代码风格与替代方案相比如何被认为是好的或干净的。考虑到相同的示例为 RowColumnPagePrinter 创建了一个类,他显然能够将事物包装到类/对象中,那么为什么这次他随机使用“静态”呢?不可能是随机的,但他似乎并没有在例子后面的文字中解释他的推理。
-
我猜它只是让它更容易访问,这样你就不需要创建一个对象来生成和读取素数。它是一种将所有用于一个目的的变量和函数打包到一个类中的方法,同时避免了需要从对象调用所有内容的那种笨拙语法
-
@Mitchel0022 这似乎是一个滑坡,因为如果它是静态的,所有东西都可以被认为更容易访问,但在大多数情况下,它会导致糟糕的设计。制作一个对象并调用它似乎并没有违反书中的任何规则,而且他这样做是为了很多其他的事情,如果是这样的话,这些事情也可能是静态的。将简单的东西融入自己的课堂似乎是本书的重点,所以我觉得很奇怪他在这里不这样做。
-
他的意图可能是
primes是唯一的数学值;一旦计算出来,就没有意义(而且很昂贵)重新计算它们。
标签: java code-formatting