我目前开发了一个相当大的应用程序,其中包括计算数学问题。计算是在类中进行的,我们将它们称为A和B,它们具有一些随机的final属性和一个(唯一的)final int id作为实例变量。
我希望能够在测试模式下运行程序,在每次执行中,随机变量完全相同,并允许我使用Junit测试将结果与手工计算进行比较。显然,我不希望在每次代码更改后重新计算我的示例解决方案(例如,如果插入了先前对prng的访问,这将移动所有随机数)。
请注意,我目前使用Java.util.Random作为prng,但我愿意接受建议。
现在的问题是:我应该如何构建实例化和访问prng?要指出问题,请注意以下是非常糟糕的方法:
我提出了以下解决方案(主要基于this answer),但不完全相同,因为编程语言和测试种子生成是不同的。
public class PRNGeneratorGenerator{
//Make class a singleton
private PRNGeneratorGenerator instance;
private PRNGeneratorGenerator() {}
public PRNGeneratorGenerator getInstance(){
if (instance == null) instance = new PRNGeneratorGenerator();
return instance;
}
//RandomNumberGenerator-Methods and Attributes
private boolean isTestMode = false;
private Random seedRng = new Random();
public void setTestMode(boolean testMode){
isTestMode = testMode;
}
public Random getPseudorandomNumberGenerator(long testSeed){
if(isTestMode) return new Random(testSeed);
return new Random(seedRng.nextLong());
}
}
具有最终随机数的类(上面名为A和B)将如下所示:
public class A{
private final static long CLASS_SEED = 872349;
private final int randomNumberOne;
private final int randomNumberTwo;
private final int id;
public A(int id){
this.id = id;
long testSeed = CLASS_SEED + id;
Random rnd = PRNGeneratorGenerator.getInstance().getPseudorandomNumberGenerator(testSeed);
randomNumberOne = rnd.nextInt();
randomNumberTwo = rnd.nextInt();
}
}
在测试模式下,我会在开始任何实例化之前调用PRNGeneratorGenerator.getInstance().setTestMode(true)
。
这是解决我在java中的问题的好方法还是这种方法有任何缺点?我已经阅读了许多类似的问题,但没有找到能回答我问题的同等问题。提前感谢您的回答。
答案 0 :(得分:2)
我建议创建一个“PRNGeneratorGeneratorTest”类,它创建自己的PRNGeneratorGenerator本地实例进行测试。改组测试&是一个坏主意。生产代码有很多原因:例如令人困惑的是,很容易在代码中留下一些东西,这些代码可以在不需要的时候翻转模式等等。测试类还有其它好处,例如让你能够在1个版本中同时完成所有测试结果自动显示&保存
如果您不想制作测试类,至少将getPseudorandomNumberGenerator除以2(即制作测试方法):
public Random getPseudorandomNumberGenerator(){
return new Random(seedRng.nextLong());
}
public Random getPseudorandomNumberGeneratorTest(long testSeed){
return new Random(testSeed);
}
..它不是伟大的练习,但它比改组测试和生产代码要好得多。