当使用黑盒测试可测试类时,我应该避免使用Di吗?

时间:2013-06-02 11:00:36

标签: java unit-testing dependency-injection tdd

我正在实现类似于nand2tetris项目的东西,除了我在java中编写我的所有代码而不使用HDL并且我自己编写测试。 对于问题ilustration: 我已经实现了nand逻辑门,它将依赖于OR,AND,XOR和NOT逻辑门。

我怀疑这两种方法:

1)DI方法

public interface Nand {
  int nand(int a, int b);
}

public class NandImpl implements Nand {
  public int nand(int a, int b) {
    return a * b == 0 ? 1 : 0;
  }
}

public interface And {
  int and(int a, int b);
}

public class AndImpl implements And {
  Nand nand;

  public AndImpl(Nand nand) {
    this.nand = nand;
  }

  public int and(int a, int b) {
    return nand.nand(nand.nand(a, b), nand.nand(a, b));
  }
}

2)没有DI的方法

public class NandImpl {

  static NandImpl singleton = null;

  protected NandImpl() {
  }

  public static NandImpl getInstance() {
    if(singleton == null) {
      singleton = new NandImpl();
    }
    return singleton;
  }

  public int nand(int a, int b) {
    return a * b == 0 ? 1 : 0;
  }
}

public class AndImpl {

  static AndImpl singleton = null;
  NandImpl nand;

  protected AndImpl() {
    nand = NandImpl.getInstance();
  }

  public static AndImpl getInstance() {
    if(singleton == null) {
      singleton = new AndImpl();
    }
    return singleton;
  }

  public int and(int a, int b) {
    return nand.nand(nand.nand(a, b), nand.nand(a, b));
  }
}

我从1开始接受aproach但是我现在有一个疑问,因为我总是需要在测试中存储依赖关系以实现真正的实现,这对我来说似乎有点不对。 此外,我在DI上看不到任何优势,因为我可以使用真值表完全测试AND,OR,NOT和XOR实现。

我更喜欢哪种方式?

1 个答案:

答案 0 :(得分:3)

考虑一下如何使用实际的逻辑门。

您通常有两个输入,一个输出和一个黑盒子。无论是NAND,AND,OR还是其他任何东西都没关系 - 界面看起来完全相同。所有逻辑门看起来都一样。如果你的电路采用不同的逻辑门,你可以将它们中的任何一个插入其中并获得不同的行为。

因此,您的界面命名是问题的一部分。这不是具有实现的NAND或AND,它是LogicGate,可以实现为NAND或AND。

如果你这样做,很明显AND门不能仅仅依赖于传递给它的任何东西的实现。它需要实际的与非门,或其他一些使其工作的方式。

当使用合作者的东西可以完全信任它们时,DI是合适的,并且不需要知道它们的实现。这不是这种情况 - 并且可能有其他方法可以使AND门工作 - 所以不要使用DI。

如果有任何东西使用逻辑门而不关心它的实现 - 只要相信它正在做适当的工作,无论当时发生什么 - 然后你可以使用DI。