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

Java包之间的每个循环引用都不好吗?,java,reference,sonarqube,cyclic,Java,Reference,Sonarqube,Cyclic,我已经使用Sonar代码质量管理平台一段时间了,在大多数情况下,我发现它在揭示代码库中隐藏的设计缺陷方面非常有用 然而,有一条规则让我烦恼多于帮助,那就是检查“循环包引用”冲突 我想我完全明白在哪里,包裹之间的这种依赖是一件坏事。例如,在典型的三层表示/服务/持久性分层设计中,让数据库处理代码引用回与UI相关的类几乎总是一个坏主意。我可以称之为“违规” 但是让我们考虑其他的情况,比如设计一个IDE类应用程序。比如说,我们有一个包含应用程序接口的主包,该接口定义了引用应用程序视图的List App

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

然而,有一条规则让我烦恼多于帮助,那就是检查“循环包引用”冲突

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

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

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

当然,您可以将视图界面放入com.myapp.ui来打破这个循环。但是,当com.myapp.ui.view中有各种其他与视图相关的API时,其中许多是另一种抽象API,如AbstractView、ContentView、AbstractContentView等,我想知道出于管理目的,是否应该将它们保存在单独的包中

并认为所说的应用程序有许多类似的例子,如COM.MyApp.U.Actudio,C.MyApp.U.I.透视等,这将真正使C.MyAPP.UI PACKAGE拥挤,如果我们要把它们都放在那里。

那么,你建议用什么方法来处理这种情况呢?真的每个循环包引用都是一件坏事吗?或者如果我不得不和他们住在一起,你如何配置声纳来只检查真实的、有问题的周期

谢谢

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

但是,如果您引入了循环依赖,那么有必要询问您是否真的需要它,以及为什么需要它。tl;dr是指,通常情况下,您可能会发现打破循环可以提高模块化程度,尤其是单独测试组件的能力

举个例子,视图真的需要一个
getApplication()
,它可能返回一个相对“重”的对象(即本身需要数据库、网络等的对象)?大概但也许不是。如果您真正需要从
getApplication
中获得一些回调(例如当用户启动一些操作时),那么在一些公共包中为回调创建一个接口可能会很有用。因此,不是:

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()

你应该问的问题是:这给了我什么?这可能是因为你必须删掉太多的内容,以至于没有给你太多的东西——尽管这可能意味着你可以把你的课程分开一些。但它可能会使测试视图变得更容易,因为现在您的单元测试可以(1)在不启动整个应用程序的情况下测试视图,以及(b)提供一个“虚拟”回调,该回调的作用类似于保存描述操作的字符串,然后,您的单元测试断言它保存了正确的字符串。

事实上,存在一个开放的JIRA票据,以防止将父/子包之间的循环视为质量缺陷:

请让我尝试想出一个可以证明View.getApplication()正确的案例。我认为视图引用通常与应用程序相关的其他资源可能是一个常见的要求,如i18n消息包或JDBC数据源等。也许我们都可以用DI的方式对它们进行分类,但我相信根据定义,在这种情况下,视图是复合整体的一部分,不能在单独的上下文中进行思考。因此,JDBC数据源不能是任意的,而是其父应用程序提供的数据源。在设计中显示这种依赖性不是更清楚吗?