java - Java 包之间的每个循环引用都不好吗?

标签 java sonarqube cyclic-reference

<分区>

我使用 Sonar 代码质量管理平台已有一段时间了,在大多数情况下,我发现它对揭示代码库中隐藏的设计缺陷非常有帮助。

但是,有一条规则给我带来的麻烦多于帮助,那就是它检查'循环包引用' 违规行为。

我想我完全理解包之间的这种依赖性在哪里是一件坏事。例如,在典型的 3 层表示/服务/持久层设计中,让数据库处理代码引用回 UI 相关类几乎总是一个坏主意。我不介意称之为“违规”

但是让我们考虑其他情况,例如设计类似 IDE 的应用程序。比如说,我们有一个包含 Application 的主包接口(interface),它定义了 List<View> Application.getViews()引用应用程序 View 的方法。

但是,当 View接口(interface)有一个 Application getApplication()引用其父应用程序的方法,我认为这是一个很常见的设计,它将引入循环引用,前提是每个接口(interface)都在 com.myapp.ui 中分开。 , 和 com.myapp.ui.view分别。

当然,你可以只把View界面进入com.myapp.ui打破循环。但是当您在 com.myapp.ui.view 中有各种其他与 View 相关的 API 时,其中许多是另一种抽象 API,如 AbstractView , ContentView , AbstractContentView等。我想知道出于管理目的,将它们放在单独的包中是否更可取。

考虑到上述应用程序还有许多其他类似情况,例如 com.myapp.ui.action , com.myapp.ui.perspective , 等等,这真的会使 com.myapp.ui如果我们要把它们都放在那里,包裹会很拥挤。

那么,您建议采用什么方法来处理这种情况?真的每个循环包引用都是坏事吗?或者,如果我不得不忍受它们,您如何配置 Sonar 以仅检查真实的、有问题的周期?

最佳答案

每个绝对值——除了这个 ;)——有时都会出错。那么,每个循环引用都是坏的吗?不,你必须使用你的判断。

但是如果你确实引入了循环依赖,那么值得问问你是否真的需要它,以及为什么。 tl;dr 通常是这样,您可能会发现打破循环可以提高您的模块化,尤其是您单独测试组件的能力。

使用您的示例, View 是否真的需要 getApplication(),它大概会返回一个相对“繁重”的对象(即,一个本身需要数据库、网络等的对象)? 也许……但也许不是。如果您从 getApplication 真正需要的是带有一些回调的东西(例如当用户启动某些操作时),那么在一些通用包中为该回调创建一个接口(interface)可能会很有用。所以,而不是:

com.foo.app.Application
com.foo.view.View
    Application getApplication()

你会:

com.foo.common.Callback // maybe just a Callable, Runnable, etc?
com.foo.app.Application
    provides a Callback for some action foo
com.foo.view.View
    Callback getFooCallback()

您应该问的问题是:这给我带来了什么?可能是你不得不放弃太多,以至于它不会给你太多——尽管这可能表明你可以将你的类(class)分开一些。但这可能实际上使测试您的 View 变得更容易,因为现在您的单元测试可以 (1) 测试 View 而无需启动整个应用程序,以及 (b) 提供一个“虚拟”回调来执行类似保存描述操作的字符串,然后您的单元测试断言它保存了正确的字符串。

关于java - Java 包之间的每个循环引用都不好吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16535479/

相关文章:

java - 如何找到数据库的最后一个条目

java - 正确设置SonarQube以覆盖代码

ruby-on-rails - 制造 gem 循环依赖

c++ - shared_ptr 和循环引用

java - 我在调用矩形面积的方法时遇到问题

java - 我的 java 计算器需要帮助

java - 对象数组的 getter 和 setter?

java - Sonar "duplicated code"在哪里?

postgresql - sonar启动时无法连接postgreSQL

java - 使用 Ant 构建包含混合 Scala 和 Java 源文件的项目 - 非法循环引用错误