Java项目中组织包的优缺点

3
随着我所涉及的项目越来越庞大,我开始对将类划分为包变得相当不确定。假设该项目有许多层次结构,在这些层次结构中有接口和实现甚至更多的子层次结构(组件)。我最终总是得到了很多包,这开始变得有点混乱。
因此,我想知道其他人处理包的方法。您喜欢有很多只包含少量类的包还是只有少数包含大量类的包?您喜欢将实现与接口分开吗?等等……通常情况下,您使用包的日常习惯以及您方法的优缺点。
感谢您的帖子。
2个回答

10

软件包的目的是帮助你找到需要的东西。

如果它们比平时更加复杂,那么你可能没有做正确。如果软件包的结构不够直观,实际上在查找类时会比扁平结构更难。

据我所知,将类组织成软件包有两种基本方法:

  1. 先按模块组织。这里,你的高级软件包是系统的不同模块,你可以根据功能进一步分割。
  2. 先按功能组织。这里,你首先按功能组织(例如将所有控制器类放入一个软件包中,将所有数据容器放入另一个软件包中等),然后可以选择按模块进行细分。

这两个系统都有其优缺点,我发现它们大致相等,但我稍微更喜欢模块化方法。

真正重要的是要遵循一个系统,不要混淆两个系统。不要强行将类‘塞’到它们不属于的软件包中,如果你的新类似乎不属于任何现有类别,则不要害怕创建新软件包。

如果一个软件包看起来过大,你可能需要将其拆分。但是,是否应该拆分软件包的决定应基于其中类之间是否有明显的概念界限,而不是基于数量。如果只有一个类的软件包和拥有30个类的软件包一样好,只要它们存在时显然是有原因的。

至于接口和实现的分离,首先,我可能会质疑它们的必要性。我经常遇到只有一个合理实现的接口,这使我质疑它们的存在理由。(有时确实有很好的理由,但往往没有。)

但如果您有多个实现针对给定接口,那么是的,我会将它们分开。接口将是com.foo.Bar,而实现将是类似于com.foo.bars.CrowBarcom.foo.bars.TaskBar等内容。显然,如果您的实现属于不同的模块,则可以更改为com.foo.moduleX.bars.CrowBarcom.foo.bars.moduleX.CrowBar,具体取决于您遵循的系统。

重新阅读所有内容,似乎有点复杂,但可能第一句话最重要:不要盲目遵循包装原则,包应该帮助您找到类,而不阻碍您。


谢谢您详尽的回答。我脑海中有一个问题,关于模块中的子模块,您是否也会为它们创建包?例如 com.foo.moduleX.submoduleX.com.foo.moduleX.submoduleY. - michal.kreuzman

2
我更喜欢将我的类和方法的范围限制为私有或包保护(以避免混乱Eclipse的自动完成 :)),这意味着一个包可以包含相当多的类。
我更喜欢将业务数据对象(DAO)与它们的存储库/检索服务分开,这些对象与业务逻辑对象和视图分开。
没有交叉依赖的相关功能集通常会放在自己的构件中,因为我倾向于重用逻辑。当您开始使用OSGi和独立服务时,这尤其方便。
重要的一点是,公开导出的接口(公共接口、枚举和类)需要有一定的相关性,以便包文档显示一定的内聚性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接