从编码风格的角度来看,循环类依赖是不是很糟糕?

时间:2009-08-31 07:49:01

标签: language-agnostic oop dependencies

从编码风格的角度看,循环类依赖是不是很糟糕?

示例:

在数据库应用程序中,我们有两个类,一个封装有关单个数据库(DBInfo)的信息,另一个类可以创建数据库连接。 (ConnFactory

DBInfogetConnection方法,使用ConnFactory创建连接。但ConnFactory本身需要DBInfo个对象才能这样做。

像这样:(为了便于阅读,忽略了任何编码风格)

class DBInfo {
    String name;
    String connectionUrl;

    Connection getConnection() {
        return ConnFactory.getConnection(this);
    } 
}


class ConnFactory {
    Connection getConnection(DBInfo toWhat) {
        return new Connection(toWhat.connectionUrl);
    }
}

我的同事认为这是不好的做法,如果只有一个依赖方向而没有像这里那样的循环方向会更好。

这是一种不好的做法,反模式还是代码味道?有什么缺点吗?

7 个答案:

答案 0 :(得分:15)

一般来说,我会将循环依赖称为Code Smell。请注意,术语“代码嗅觉”主要表示“这里是一段需要特别注意的代码,并且可能会从重新设计中受益。”

在大多数情况下,我会强烈考虑一种不需要循环依赖的设计,但在极少数情况下可能没问题。

在您的示例中,ConnFactory似乎是多余的,但这可能是因为您的示例已被削减。但是,在我看来,如果它被移动到DBInfo类,那么Connection创建逻辑会更好。如果您已经有一个包含数据库数据的类,那么让它负责创建与该数据库的连接似乎很自然。

答案 1 :(得分:8)

是的,一般来说,循环依赖是坏的,虽然并不总是邪恶的。当一个模块中的更改传播到其他模块时,循环依赖的问题包括紧耦合,相互依赖的模块以及通常的多米诺效应。

尽管如此,您的代码违反了单一责任原则,因为DBInfo不仅存储有关数据库的信息,还负责获取Connection个对象。将该特定功能删除到单独的类中,一切都会好的。

答案 2 :(得分:7)

不一定

我不认为粒度级别的循环依赖性不好。如果两个,三个或者四个类相互依赖,我没有看到问题。 (我不是说这是你想要的东西,但在某些情况下可以没问题。)

如果您在程序包或模块级别具有相互依赖性, 是一个问题,原因如上所述。

答案 3 :(得分:4)

此代码仅在ConnFactory.getConnection()为静态时有效。更好的解决方案是使getConnection()成为ConnFactory的实例方法。然后你的DBInfo可以使用ConnFactory作为参数(如果你有一个重载的构造函数,可能在构造函数中)。但是,我认为在这种情况下使用静态方法比循环引用更糟糕。

但是,如果您要走这条路线,我还会创建IConnFactoryDBInfo进行互动且ConnFactory将实施的界面DBInfo。然后没有循环引用 - ConnFactoryIConnFactory都取决于{{1}},这两者都不依赖。

答案 4 :(得分:2)

我所知道的是,当您开始使用结构图等依赖注入框架时,循环依赖可能会成为一个问题。大多数这些框架在处理循环依赖时遇到问题,有时会导致堆栈溢出异常(请原谅双关语:-))因此,除非绝对必要且无法避免,否则我倾向于避免使用它。

答案 5 :(得分:1)

在使用ORM层的任何应用程序中,这种常见情况的双向一对多关系怎么样?这不是循环依赖的情况吗?

这是不好/代码味?

答案 6 :(得分:0)

循环依赖性很糟糕,因为:

  • 两个依赖项不止一个
  • 你不能逐步测试(没有嘲笑其中一个,这对于小的,紧密耦合的东西来说是愚蠢的。)

如果需要,您可以使用接口完成所有内容以打破循环依赖关系,但直接的最小解决方案是使DBInfo成为ConnFactory的嵌套类。引用自身的单位不是循环的。