gpt4 book ai didi

java - 如何设计可用于测试的伪随机数生成器模式?

转载 作者:行者123 更新时间:2023-12-02 05:06:19 24 4
gpt4 key购买 nike

我目前开发了一个相当大的应用程序,其中包括计算数学问题。计算是在类中进行的,我们称它们为 A 和 B,它们有一些随机的最终属性和一个(唯一的)最终 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 问题的好方法吗?这种方法有什么缺点吗?我读过许多类似的问题,但没有找到可以回答我的问题的等效问题。预先感谢您的回答。

最佳答案

我建议创建一个“PRNGeneratorGeneratorTest”类,它创建自己的 PRNGeneratorGenerator 本地实例以进行测试。由于多种原因,混洗测试和生产代码是一个坏主意:例如这很令人困惑,很容易在测试的代码中留下一些东西,在不需要的时候打开模式,等等。无论如何,测试类还有其他好处,例如让您能够在 1 个构建中同时执行所有测试结果自动显示并保存

如果你不想创建一个测试类,至少将 getPseudorandomNumberGenerator 除以 2(即创建一个测试方法):

public Random getPseudorandomNumberGenerator(){
return new Random(seedRng.nextLong());
}

public Random getPseudorandomNumberGeneratorTest(long testSeed){
return new Random(testSeed);
}

..这不是很好的做法,但它比打乱测试和生产代码要好得多。

关于java - 如何设计可用于测试的伪随机数生成器模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27757202/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com