0

我不久前收到了这个编程任务,但我仍然对看起来像控制反转的要求感到困惑。

作业:用Java编写一个简单的随机数生成器服务。该服务应至少提供但不限于两种不同的随机数生成器实现——一种使用 Java 的内置随机数生成器,另一种使用采用作者选择的算法的生成器。评估者应该能够使用代码和编译的类来插入他们自己的随机数生成器实现,而无需重新编译代码。

我的问题是最后一行。那不需要一些 API 或接口规范来知道如何使用另一个 RNG 类吗?当我完成分配时,我让主程序将类名作为参数,然后调用该类的 main 方法。显然这不是正确的做法,因为我最终没有得到这份工作。

我错过了什么吗?有没有办法做到这一点,而不会对“插入”的类做出很大的假设?

注意:这是从 2010 年开始的,它不是当前的工作面试任务。另外,我不是要求某人发布作业的答案,只是为了澄清作业的最后一行。

TIA

4

2 回答 2

1

评估者应该能够使用代码和编译的类来插入他们自己的随机数生成器实现,而无需重新编译代码。

听起来他们希望您对接口进行编码。我不知道他们是否希望您扩展Random类或其他一些 API 合同。但是他们希望您能够使用不同的随机发生器即插即用,而无需重新编译您的代码。

这与控制反转的关系是您的班级将随机数生成委托给随机发生器。这个随机化器通过设置器或构造器传递到服务实现中。

所以你的班级可能看起来像

class RandomizerService{

    private Random rand;

    public RandomizerService{Random rand){
        this.rand = rand;
    }

    public int getRandomInt(){
        return rand.nextInt();
    }
}
于 2013-10-01T19:44:01.453 回答
0

为接口提供可插拔架构并不难。普通的 JRE 提供了必要的功能,而不需要额外的框架。因此,如果您有一个接口serviceexample.RandomNumberGenerator,则可插入 RNG 的代码可能如下所示:

package serviceexample;

import java.util.Iterator;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;

public final class RngService
{
  private RngService(){}

  private static final ServiceLoader<RandomNumberGenerator> LOADER
    = ServiceLoader.load(RandomNumberGenerator.class);

  public static RandomNumberGenerator getRandomNumberGenerator()
  {
    return LOADER.iterator().next();
  }

  public static Iterator<RandomNumberGenerator> getAllRandomNumberGenerators()
  {
    return LOADER.iterator();
  }

  public static RandomNumberGenerator getSpecificRandomNumberGenerator(String name)
  {
    try
    {
      return Class.forName(name).asSubclass(RandomNumberGenerator.class).newInstance();
    } catch(InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException ex)
    {
      throw new ServiceConfigurationError(name, ex);
    }
  }
}

这个类允许应用程序只请求一个实现,浏览所有可用的实现或请求一个特定的实现。后者可以由系统属性提供,例如-Drng=class. 所以最简单的用法是RandomNumberGenerator r=RngService.getRandomNumberGenerator();. 更高级的用途是:

String name=System.getProperty("rng");
RandomNumberGenerator r=name!=null?
  RngService.getSpecificRandomNumberGenerator(name):
  RngService.getRandomNumberGenerator();

现有实现类由META-INF/serviceexample.RandomNumberGenerator包含特定实现的 jar 文件中的文件指定。另请参阅http://docs.oracle.com/javase/6/docs/technotes/guides/jar/jar.html#Service%20Provider

于 2013-10-02T14:34:03.913 回答