类之间的循环依赖:它们为什么不好,如何消除它们? [英] Circular dependencies between classes: why they are bad and how to get rid of them?

查看:28
本文介绍了类之间的循环依赖:它们为什么不好,如何消除它们?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我的项目是一堆依赖项。有没有一种方法可以消除错误的依赖,然后保持清晰度?

推荐答案

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

两个原因:

  1. 可维护性。

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

    为什么分层代码意味着可维护性?因为,每次更改 类,则可以确保它下面的任何内容都不会受到影响。这些知识使维护和开发 该系统更便宜,更不容易出错。

    好消息是,使用像Visual Studio这样的现代开发工具, EclipseNetBeans,以及 IntelliJ,相当 很容易为您的项目生成图表。如果还没有工具,则会出现simple trick

  2. 可靠性。

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

是否有好的CID?

有些CID是有效的、有帮助的,并且不会影响可维护性或可靠性:字符串和对象、文件和文件夹、节点和边缘。通常,这样的循环位于一个包中,不会在包之间形成循环依赖关系。

如何检测包CID?

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

如果您的项目很大,或者您希望持续监视CID,那么实现一个使用 用于检测CID的反射(深度优先遍历类或包,并在第一个反向引用处停止)。

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

我的项目是一堆依赖项。是否有解决此问题的方法?

是的,有。以下是步骤:

  1. 设计所需的结构。

    A.创建现有程序包的普通列表,如下所示:

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

    B.组织包裹。
    重新排序列表,以使抽象级别较低的包更接近底部,而具有 抽象级别越高,越接近顶层。 如果包同时包含低抽象级别和高抽象级别的类,您可能希望将该包一分为二。

    如果您有太多的包,首先将它们拆分成层,对层进行排序,然后在这些层中对包进行排序。 此步骤应该会产生您想要的包顺序,其中您希望依赖项向下而不是向上。

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

  2. 使过程可度量。

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

    /li>
  3. 逐一解析错误依赖。通常,从下到上更容易,正如您想要澄清的那样 基础知识先行。

    这些提示可能会有所帮助:

    A.您有一个"死星"或"上帝对象",即它所知道的类所知道的对象。 换句话说,这样的类是许多循环依赖的一部分,这些循环依赖可能导致每个循环依赖 几乎所有其他类上都有。

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

    B.您没有类之间的圆,只是包之间的圆。

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

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

    解决方案:
    使用回调接口或回调方法(模式观察器)。

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

    解决方案:

    • 将这些类合并为一个类。
    • 将类放入一个包中,并将它们的关系声明为良好的CID。
    • 为其中一个类创建一个Factory类和接口。

如何保持项目的清晰度?

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

如果项目又大又复杂,您应该建立一个流程,以便在每次有人 在错误的依赖项中编译或签入。

这篇关于类之间的循环依赖:它们为什么不好,如何消除它们?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆