【问题标题】:Java Inversion of Control programming assignmentJava 控制反转编程作业
【发布时间】:2013-10-01 19:38:46
【问题描述】:

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

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

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

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

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

TIA

【问题讨论】:

  • 我在 2008 年有一个类似的,用于调度程序,但也有类似 AOP 的元素,所以不难看出他们想要 Spring ......我认为这个问题想要看看你可以使用 IOC 容器来完成这些工作。不过这个问题不适用于Stack Overflow,请阅读FAQ

标签: java controls inversion-of-control


【解决方案1】:

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

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

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

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

class RandomizerService{

    private Random rand;

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

    public int getRandomInt(){
        return rand.nextInt();
    }
}

【讨论】:

  • 这不仅仅是对接口进行编码,它可以是硬编码的。 “无需重新编译”意味着,正如 OP 所怀疑的那样,他需要进行依赖注入。
【解决方案2】:

为接口提供可插拔架构并不难。普通的 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();

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 2014-10-13
    相关资源
    最近更新 更多