这是循环依赖吗?

这段代码是循环依赖的一个例子吗?

package expr; import sheet.Sheet public class AdressExpr implements Expr { private Address address; private Sheet sheet; public double value(Sheet sheet) { return sheet.value(address); } } public interface Expr { public double value(Sheet sheet); } public class Adress { // omissions } package sheet; import expr.Address; import expr.Expr; public class Sheet implements SuperSheet { private Map 
map; public double value(Address address) { return map.get(Address).value(this); } } public interface SuperSheet { public double value(Address address); }

我知道这个例子是糟糕的编程,但由于值方法的缘故,接口是否禁止循环依赖?

我认为在类图中更容易看到。 如您所见, Sheet concrete类和Expr接口之间确实存在循环依赖关系。 我不会说它非常糟糕,因为我认为2个具体类之间的循环依赖性是最差的……如果可能的话,这样做当然不可取。

你的守则

在此处输入图像描述

因此,也许您可​​能考虑重构的方法之一是让您的AddressExpr依赖于SuperSheet而不是SheetExpr来依赖于SuperSheet而不是Sheet : –

 public class AdressExpr implements Expr { private Address address; private SuperSheet sheet; public double value(SuperSheet sheet) { return sheet.value(address); } } public interface Expr { public double value(SuperSheet sheet); } ... ... 

…这将删除任何不需要的循环依赖项。

可能的重构代码

在此处输入图像描述

注意 :我并不是说这是解决方案。 我只是说你当然可以看看重构代码的方法,以最小化或删除循环依赖,因为循环依赖会使你的代码难以进行unit testing。 对接口进行编码总是有助于删除不需要的循环依赖。 它还使您的代码更容易进行unit testing,因为您可以轻松地模拟对象。

这是一个非常时髦的例子。 我将在这里对我的思考过程非常冗长,因为我怀疑有一些愚蠢的命名正在进行中。

包:sheet expr

表格内容:

  • SuperSheet

expr的内容:

  • AddressExpr
  • EXPR
  • 地址

每个用法:

  • AddressExpr – Expr,Address,Sheet
  • 表 – 超级表,地址

我们看到AddressExpr依赖于Sheet,它位于工作表包中。 一个依赖下来。

我们还在expr包中看到Sheet依赖于Address。

因此,工作表和expr包之间存在循环依赖关系。 (注意:工具可以显示这一点。我手工完成,因为你的问题非常抽象。查看JDepend)

另外,我甚至不确定我是否听说过一种价值方法。 如果编译器可以理解双向接口的使用,那么它将起作用。 它有解开混乱的感觉。

至少在包级别上。 包装sheet取决于包装expr ,反之亦然。 根据自己的经验 – 我会重构这个。