类之间的循环依赖:它们为什么是坏的以及如何摆脱它们?

时间:2017-03-26 00:02:30

标签: design-patterns dependencies dependency-management circular-dependency

我觉得循环依赖(又称循环引用)意味着糟糕的设计并损害项目。我怎样才能说服我的队友和我的经理?

我的项目是依赖性混乱。有没有一种方法可以摆脱错误的依赖关系,然后保持清晰度?

2 个答案:

答案 0 :(得分:5)

为什么循环依赖(CiD)不好?

有两个原因:

  1. 可维护性。

    您希望您的代码是分层的,即您希望有一个自上而下的依赖关系图(一个图表显示所有箭头向下,没有箭头向上)。 如果您有CiD,则您的代码不是分层的。

    为什么分层代码意味着可维护性?因为,每次更改一个界面 上课时,你可以确定它下面的任何东西都不会受到影响。这种知识使维护和发展 系统更便宜,更不容易出错。

    好消息是,使用像Visual Studio这样的现代开发工具, EclipseNetBeans,和 IntelliJ,这是公平的 易于为您的项目生成图表。

  2. 可靠性。

    您不希望在生产中出现意外的无限递归。例如,当您的配置想要时 记录错误,您的错误记录器想要从配置中读取日志文件的名称(您的测试将会 传递,因为测试环境中没有错误)。 (不幸的是,意外的递归可能是 即使没有CiD也能发展。)

  3. 是否有良好的CiD?

    某些CiD有效,有用,并且不会影响可维护性或可靠性:字符串和对象,文件和文件夹,节点和边缘。通常,这样的圆圈位于一个包中,并且不会影响包之间的循环依赖。

    如何检测软件包CiD?

    您可以在依赖关系图上直观地检测CiD(请参阅上面的生成工具链接)。

    如果您的项目很大或者您想要持续观察CiD,那么实现一个使用的工具很简单 反射以检测CiD(遍历类或包深度优先并在第一个反向引用处停止)。

    注意,如果一个包在其他包中声明,这并不意味着它们彼此依赖,除非它们的类相互引用。

    我的项目是依赖性混乱。有没有一种方法可以解决它?

    dependency mess 就在这里。以下是步骤:

    1. 设计所需的结构。

      一个。创建现有包的简单列表,如下所示: enter image description here

      如果您的包结构是分层的,请将其展平,并且不要忘记根包。

      湾整理包裹。
      重新排序列表,以便具有较低抽象级别的包更接近底部并使用a打包 更高的抽象级别更接近顶部。 如果包中包含低和高抽象级别的类,您可能希望将此包破解为两个。

      如果您有太多的包,首先将它们分成几层,订购图层,然后在这些图层内订购包。 此步骤应该会产生所需的包顺序,您希望依赖关系在哪里停止而不是。

      ℃。以相同的方式组织包中的类。

    2. 使流程可衡量。

      测量到所需结构的距离,以便在接近目标时可以看到进度。 对于每个类,计算错误依赖项的数量(指向的依赖项)。这些数字的总和将 成为您的指标。最后,它将为零 设置监视以检测新的错误依赖项。你想在他们之前阻止你的队友(和你自己) 即将检查另一个错误的依赖。

    3. 逐个解决错误的依赖关系。通常,从底部到顶部更容易,因为您需要澄清 首先是基础知识。

      这些提示可能有所帮助:

      A。你有一个"死亡之星“或”上帝对象“,即一个知道的类所知的对象。在 换句话说,这样的类是许多循环依赖的一部分,这可能导致每个循环的依赖性 几乎所有其他班级都上课。

      解决方案:
      大多数死亡之星可以通过将它们分成两个(或更多)类来解决,其中一个类只包含 状态和非常基本的操作,另一个类包含高级操作(通常第二个类是静态的)。 enter image description here

      B。您之间没有圈子,只是在包之间。

      解决方案:
      考虑将一些类移到其他包中。

      C。您有一个使用某些上层类方法的类,但不拥有其实例化。

      解决方案:
      使用回调接口或回调方法(模式Observer)。 enter image description here

      D。您有两个相互创建并使用彼此方法的类。

      解决方案:

      • 将班级合并为一个班级。
      • 将这些课程放在一个包中,并将他们的关系声明为一个好的CiD。
      • 为其中一个类创建一个Factory类和接口。
    4. enter image description here

      如何在项目中保持清晰度?

      如果你有一个小团队和一个小项目,只需向你的队友解释规则,偶尔检查图表。

      如果项目规模庞大且复杂,您应该建立一个过程,以便每次有人接收警报或拒绝 编译或检查错误的依赖项。

答案 1 :(得分:1)

首先,当您的项目如此简单时,没有任何反模式设计可能会产生问题,并且确实使事情变得更容易。它只会在项目变得复杂时出现问题。选择平衡点和右边是设计的一部分。为了说服某人,当你得到一个人时总是需要一个真正的错误。

简要说明处理循环依赖关系时,您总是需要将其与多任务分开。例如:enter image description here

原则是让每个单位专注于其核心业务或服务。如果你有一个圈子有时意味着你建立一个多核业务的单位。但实际上总是有更多的矿工周期,因为真正的业务流程就像这样。当它与单元的核心无关时,它是可以的。

是的,有人可以帮我内联图片吗?感谢。