如何组织包(并防止依赖周期)?

我一直在我的Java项目上运行一些指标,显然包之间有很多依赖周期。我真的不知道如何将东西组织成包,所以我只是做了对我有意义的事情,这显然是错误的。

我的项目是一个神经网络框架。神经网络具有神经元,它们通过连接相互连接。他们需要相互依赖。但是,也有不同类型的神经元,所以我认为将它们全部放在自己的“神经元”包中是个好主意。显然,连接不是神经元,所以它不应该在包中,但是由于它们相互引用,我现在有一个循环依赖关系。

这只是一个例子,但我有更多这样的情况。您如何处理这些情况?

另外,我读到包层次结构中较高位置的包中的类不应该引用更深的包中的类。这意味着包“nn”中的NeuralNetwork类不能引用包“nn.neurons”中的神经元。你们遵循这个原则吗?如果我将NeuralNetwork移动到“nn.networks”或其他东西呢?在这种情况下,它将是指同级包而不是子包。这是更好的做法吗?


答案 1

antcontrib VerifyDesign 任务将帮助您完成所需的操作:

例如,如果一个源树中有三个包

* biz.xsoftware.presentation
* biz.xsoftware.business
* biz.xsoftware.dataaccess

自然,表示应该只依赖于业务包,而业务应该依赖于数据访问。如果您以这种方式定义设计并且违反了它,则在调用验证设计蚂蚁任务时,构建将失败。例如,如果我在 biz.xsoftware.presentation 中创建了一个类,并且该类依赖于 biz.xsoftware.dataaccess 中的一个类,则生成将失败。这确保了设计实际上遵循了所记录的内容(至少在某种程度上)。这对于自动构建尤其好。

因此,一旦你决定了应该如何组织事情,你就可以在编译时强制执行需求。您还可以获得精细的控制,因此您可以允许某些情况违反这些“规则”。所以你可以允许一些周期。

根据你想要如何做事,你可能会发现“utils”包是有意义的。

对于您引用的特定案例...我可能会做这样的事情:

  • 包 nn 包含 Nueron 和 Connection
  • 包 nn.neurons 包含 Nueron 的子类

神经元和连接都是NeuralNetowrk中使用的高级概念,因此将它们放在一起是有意义的。神经元和连接类可以相互引用,而连接类不需要知道神经元子类。


答案 2

首先,您有理由担心,因为包之间的循环依赖关系很糟糕。由此产生的问题随着项目规模的增长而变得越来越重要,但没有理由按时解决这种情况。

应通过将一起重用的类放在同一包中来组织类。因此,如果你有例如 AbstractNeuron 和 AbstractConnection,你可以把它们放在同一个包里。如果你现在有HumanNeuron和HumanConnection的实现,你可以把它们放在同一个包里(例如*.network.human)。或者,您可能只有一种类型的连接,例如 BaseConnection 和许多不同的神经元。原则保持不变。您将BaseConnection与BaseNeuron放在一起。HumanNeuron与HumanSignal等一起在自己的包装中。VirtualNeuron与VirtualSignal等你说:“显然,连接不是神经元,所以它不应该在包里..”。这并不明显,确切地说也不正确。

你说你把所有的神经元都放在同一个包装里。这两者都不正确,除非您一起重用所有实现。再次,看看我上面描述的方案。您的项目太小,以至于您将所有内容都放在单个包中,或者开始按所述组织包。有关更多详细信息,请查看通用重用原则

包中的类一起重用。如果重用包中的某个类,则重用所有类。