当前位置: 首页 > 知识库问答 >
问题:

为什么所有领先的开源Java库的包之间都有循环依赖关系?

鲁博赡
2023-03-14

在过去的几周里,我一直在研究Java包结构和依赖模式。关于这个主题的文章中的一个共同主题是包依赖关系应该形成有向无环图(DAG)的简单规则。作者Robert Martin甚至将非循环依赖原则(ADP)正式化

包之间的依赖关系结构必须是有向无环图(DAG)。也就是说,依赖关系结构中不能有循环。

一些Java库确实遵守这个简单的规则。即Spring框架库(Spring核心、Spring web等)和Google Guava。

然而,令我惊讶的是,大多数领先的开源Java项目都没有!

以下开源项目在包之间具有循环依赖关系:

  • Netflix Hystrix(每个包都是一个周期的一部分!)
  • AWS SDK
  • 公地郎
  • 公地收藏
  • 匕首
  • 谷歌Gson
  • 谷歌Guice
  • HibernateORM
  • Hibernate验证程序
  • Jackson Core
  • 乔达时间
  • 播放框架
  • 朱尼特
  • 回写
  • 码头
  • AspectJ
  • 内蒂
  • 爪哇。util
  • 爪哇。朗

我是否误解了软件工程原理?或者开发人员是否会低估这种包组织技术?

  • Spring core 4.2.3[图形][JPG]
  • 谷歌番石榴[GraphML][JPG]
  • Hystrix[图形][JPG]
  • 爪哇。util[GraphML][JPG]

共有1个答案

田博远
2023-03-14

我可以确认,在分析了许多使用JArchitect的java项目后,其中许多项目包含包之间的循环依赖关系,原因是其中许多项目选择了“按功能包”而不是“按层包”的方法。

这里有一篇很好的文章讨论了这两种方法之间的区别。

让我们以JDK中的一些包为例

这些包是按功能设计的,regex功能在java中分组。util。regex包,它需要一些来自java的安全特性。安全包和安全类还需要一些正则表达式功能。

 类似资料:
  • 我花了5个多小时试图解决这个问题。有什么问题吗? 我补充道: 组织。格拉德尔。configureondemand=true 但问题依然存在 建筑gradle(模块:应用程序) 建造。gradle(项目:myproject) //顶级构建文件,您可以在其中添加所有子项目/模块通用的配置选项。

  • 我尝试用JNI在Java项目中加载C代码。我要加载多个DLL,不幸的是,其中两个之间存在循环依赖关系:DLL a需要DLL B,而DLL B又需要DLL a!我知道在DLL之间有循环依赖关系是一种糟糕的编程设计,但在我的项目中,C代码对我来说是一个黑盒子。 有没有办法加载具有循环依赖关系的DLL? 我的代码非常简单: Java库路径是OK的,并且包含两个DLL(它作为VM参数给出,我也将其转储并在

  • 问题内容: 在几个JavaScript库中,我在一开始就看到了这种表示法: 虽然我对“立即执行的功能”语法完全满意 我想知道领先的分号是做什么用的。我所能想到的就是这是一种保险。也就是说,如果该库嵌入其他错误代码中,则它充当“最后一条语句最迟在此处结束”的减速方式。 它还有其他功能吗? 问题答案: 它使您可以安全地将多个JavaScript文件连接到一个文件中,以将其作为一个HTTP请求更快地提供

  • 我是Android编程新手。我使用Eclipse作为开发的IDE。我已经启动了一个新项目,一些jar文件被自动添加到项目中。你能解释一下这些jar文件的含义吗? Android4.4.2 android.jar < Li > Android-support-V7-app compat . jar < li>android-support-v4.jar appcompat_v7_2.jar andr

  • 当您想将库添加到您的项目时,IntelliJ IDEA中的“模块依赖项”和“库”有什么区别?此外,当您将库添加到IntelliJ IDEA中的“模块依赖项”时,“导出”复选框是什么? 在每种方式中,类和代码是如何包含在所包含的

  • 我在用Guice辅助注射。下面是一个标准场景: 现在,我可以使用Guice factory调用,并通过Guice注入的实例轻松获得我的实例。 我的问题是:如果我希望引用正在创建的的实例,该怎么办?换句话说,我想要: 我当前的解决办法相当难看:我手动创建了一个,而不使用,然后使用获取实例,并在实例上调用方法。啊!