假设我有一个直观上最好使用递归解决的问题。

我还尝试使用依赖注入使代码可测试:

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...
    }
}


}

10-04 11:08
查看更多