假设我有一个直观上最好使用递归解决的问题。
我还尝试使用依赖注入使代码可测试:
class Foo {
Bar bar;
Foo(Bar bar) {
this.bar = bar;
}
ResultType doFoo() {
...stuff...
bar.doBar();
}
}
class Bar {
Baz baz;
Bar(Baz baz) {
this.baz = baz;
}
ResultType doBar() {
...stuff...
baz.doBaz();
}
}
class Baz {
Foo foo;
Baz(Foo foo) {
this.foo;
}
ResultType doBaz() {
if (foo is needed) {
foo.doFoo(smaller problem)
} else {
...stuf...
}
}
}
现在,如果Baz不依赖Foo,则可以执行以下操作:
Foo foo = new Foo(new Bar(new Baz()));
Baz可以接受任何Foo,因此只要将它放在顶部就可以了,这没有问题。
(JVM可以处理IIRC循环)。只有Baz可以确定是否需要Foo。
以可验证的方式让Foo进入Baz的最干净方法是什么?
将
Foo
参数添加到doBaz()
是我唯一的选择吗? (暗示Foo需要将“ this”传递给doBar,然后将其传递给doBaz,等等...还是有更好的方法?)编辑:
也许问题描述确实有用。
该算法基本上是一个编译器,它以代码为输入,并输出表示代码含义的数据结构。该数据结构本质上是高度递归的。
但是,代码中可能存在不确定性(请考虑未声明的方法)。导致此问题的原因是,与大多数编译器不同,该编译器不应简单地向用户吐出一堆错误,而应向用户提供输入更多代码的选项。
基本上,编译器随后将暂时停止编译“主要”代码,并根据用户提供的新代码开始编译。此后,它将把结果数据结构附加到“主”数据结构。
如果在用户提供的此代码内还有更多的不确定性,它将再次允许用户进行澄清。
基本上,意识到代码不完整的组件(由Baz拒绝)必须调用“主”组件(Foo)以开始对用户提供的代码进行编译。
最佳答案
其他一些选择:
如果Foo
是单例(即程序中将只有一个实例),则Foo
中可以有一个静态方法返回该实例
您可以维护对“上一个”对象的引用,并从Baz使用它来回溯:
Foo类{
Bar bar;
Foo(Bar bar) {
this.bar = bar;
bar.setFoo(this);
}
ResultType doFoo() {
...stuff...
bar.doBar();
}
}
班级酒吧{
Foo foo;
Baz baz;
Bar(Baz baz) {
this.baz = baz;
baz.setBar(this);
}
void setFoo(Foo foo) {
this.foo = foo;
}
Foo getFoo() {
return foo;
}
ResultType doBar() {
...stuff...
baz.doBaz();
}
}
Baz类{
酒吧吧;
Foo foo;
Baz(Foo foo) {
this.foo;
}
void setBar(Bar bar) {
this.bar = bar;
}
ResultType doBaz() {
if (foo is needed) {
bar.getFoo().doFoo(smaller problem)
} else {
...stuf...
}
}
}