我正在实现类似于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实现。
我更喜欢哪种方式?
答案 0 :(得分:3)
考虑一下如何使用实际的逻辑门。
您通常有两个输入,一个输出和一个黑盒子。无论是NAND,AND,OR还是其他任何东西都没关系 - 界面看起来完全相同。所有逻辑门看起来都一样。如果你的电路采用不同的逻辑门,你可以将它们中的任何一个插入其中并获得不同的行为。
因此,您的界面命名是问题的一部分。这不是具有实现的NAND或AND,它是LogicGate,可以实现为NAND或AND。
如果你这样做,很明显AND门不能仅仅依赖于传递给它的任何东西的实现。它需要实际的与非门,或其他一些使其工作的方式。
当使用合作者的东西可以完全信任它们时,DI是合适的,并且不需要知道它们的实现。这不是这种情况 - 并且可能有其他方法可以使AND门工作 - 所以不要使用DI。如果有任何东西使用逻辑门而不关心它的实现 - 只要相信它正在做适当的工作,无论当时发生什么 - 然后你可以使用DI。