假设我有一个问题,直觉上最好使用递归来解决。
我也尝试使用依赖注入来使代码可以测试:
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表示)必须调用“main”组件(Foo)来开始编译用户提供的代码。
答案 0 :(得分:0)
其他一些选择:
如果Foo
是一个单例(即程序中只有一个实例),那么你可以在Foo
中有一个静态方法返回这样的实例
您可以维护对“previous”对象的引用,并使用Baz中的对象进行遍历:
class Foo {
Bar bar;
Foo(Bar bar) {
this.bar = bar;
bar.setFoo(this);
}
ResultType doFoo() {
...stuff...
bar.doBar();
}
}
class Bar { 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...
}
}
}
答案 1 :(得分:0)
您可以单独构造这些对象,然后彼此注册。
最简单的形式如下:
class Foo {
Bar bar;
void setBar(Bar bar) {
this.bar = bar;
}
ResultType doFoo() {
...stuff...
bar.doBar();
}
}
class Bar {
Baz baz;
void setBaz(Baz baz) {
this.baz = baz;
}
ResultType doBar() {
...stuff...
baz.doBaz();
}
}
class Baz {
Foo foo;
void setFoo(Foo foo) {
this.foo;
}
ResultType doBaz() {
if (foo is needed) {
foo.doFoo(smaller problem)
} else {
...stuf...
}
}
}
然后,像这样构建系统:
Foo foo = new Foo();
Bar bar = new Bar();
Baz baz = new Baz();
foo.setBar(bar);
bar.setBaz(baz);
baz.setFoo(foo);
然后,为了使其更加健壮,如果尚未建立必要的关联,您可以通过更好的异常处理来构建它。您甚至可以使用工厂方法一起创建这些对象(如上所述),以帮助确保它们不会被错误地创建。