(Java)包组织是否有最佳实践?

Cyn*_*ech 190 java naming-conventions package

不久之前,我在这里看到了一个关于java包的细粒度组织的问题.例如,my.project.util,my.project.factory,my.project.service,等.

我现在找不到,所以我不妨问一下这个问题.

是否有关于Java程序包组织的最佳实践以及它们的内容?

如何在Java项目中组织课程?

例如,我正在与一些人合作的项目有一个名为beans的包.它最初是一个包含简单豆类的项目,但最终(通过糟糕的经验和缺乏时间)包含所有内容(几乎).我通过在工厂包中放置一些工厂类(使用创建bean的静态方法的类)来清理它们,但我们有其他类来执行业务逻辑,而其他类则执行简单处理(不使用业务逻辑),如检索来自属性文件的代码消息.

感谢您的想法和意见.

ono*_*nof 163

我按功能组织包,而不是按模式或实现角色组织.我认为包裹如下:

  • 豆子
  • 工厂
  • 集合

错了.我更喜欢,例如:

  • 命令
  • 商店
  • 报告

这样我就可以通过包可见隐藏实现细节:订单的工厂,应在订单包,以便了解如何创建一个订单的详细信息是隐藏的.

  • 这是完全正确的,但很少有开发人员这样做.包应该是类的内聚集合,其中一些只在包中可见.这将最小化不应该耦合的类之间的耦合,因为它们属于不同的特征.逐包方法没有利用包可见性修改器,并且这种项目中的包具有低内聚和包之间的高度耦合. (21认同)
  • 这篇文章提到了包的可见性.我从未见过使用Java包范围,但正确的包结构可以让开发人员更好地利用它. (9认同)
  • @onof我也按功能组织代码,但是所有功能共享的基类的最佳实践是什么? (2认同)

nai*_*kus 162

包装组织或包装结构通常是一个激烈的讨论.以下是包命名和结构化的一些简单指南:

  • 遵循java 包命名约定
  • 根据功能角色及其业务角色构建包
    • 根据功能或模块细分包.例如 com.company.product.modulea
    • 进一步细分可以基于软件中的图层.但是如果你的包中只有几个类,那就不要过分了,那么把所有东西放在包里都是有意义的.例如com.company.product.module.webcom.company.product.module.util
    • 避免过度使用结构化,IMO避免单独包装异常,工厂等,除非迫切需要.
  • 如果您的项目很小,请使用很少的包保持简单.例如com.company.product.modelcom.company.product.util
  • 看一下Apache项目中一些流行的开源项目.了解他们如何使用结构化,用于各种规模的项目.
  • 在命名时还要考虑构建和分发(允许您在不同的包中分发api或SDK,请参阅servlet api)

经过一些实验和试验后,你应该能够想出一个你觉得舒服的结构.不要局限于一个约定,对变化持开放态度.

  • 我同意按功能打包最有意义。我曾经听过一个与公司办公室结构有关的比喻。在分层方法中,公司中每个级别的每个人都彼此坐在一起,即主管,经理,行政人员,雇员/工人都坐在建筑物的不同部分中。这种结构可能不如“功能”有组织的方法有效。也就是说,如果销售主管与销售经理一起坐在一起,而销售经理与所有销售经理一起坐在一起的销售员工一起。这样组织时,可以在部门之间提供更好的凝聚力。 (2认同)

Pet*_*eng 38

简答:每个模块/功能一个包,可能带有子包.将密切相关的东西放在同一个包中.避免包之间的循环依赖.

答案长:我同意这篇文章的大部分内容

  • 子包破坏封装。“子包”本身就是一个完全独立的包 (2认同)

Tho*_*ran 14

我更喜欢图层之前的功能,但我想这取决于你的项目.考虑你的力量:

  • 依赖.尝试最小化包依赖性,尤其是在功能之间.必要时提取API.
  • 团队组织.在一些组织中,团队在功能上工作,而在其他组中工作.这会影响代码的组织方式,使用它来形式化API或鼓励合作.
  • 部署和版本控制.将所有内容放入模块可以简化部署和版本控制,但更难修复错误.拆分可以实现更好的控制,可扩展性和可用性.
  • 回应变化.组织良好的代码比一个大的泥球更容易改变.
  • 大小(人和代码行).它需要越大,越正规/标准化.
  • 重要性/质量.有些代码比其他代码更重要.API应该比实现更稳定.因此需要明确分开.
  • 抽象级别和入口点.局外人应该可以知道代码是什么,以及从查看包树开始阅读的位置.

例:

com/company/module
  + feature1/
    - MainClass          // The entry point for exploring
    + api/               // Public interface, used by other features
    + domain/
      - AggregateRoot
      + api/             // Internal API, complements the public, used by web
      + impl/ 
    + persistence/       
    + web/               // presentation layer 
    + services/          // Rest or other remote API 
    + support/            
  + feature2/
  + support/             // Any support or utils used by more than on feature
    + io
    + config
    + persistence
    + web
Run Code Online (Sandbox Code Playgroud)

这只是一个例子.这是非常正式的.例如,它为feature1定义了2个接口.通常这不是必需的,但如果不同的人使用不同,可能是一个好主意.你可以让内部api扩展公众.

我不喜欢'impl'或'support'这两个名字,但它们有助于将重要性较低的东西与域名和域名分开.在命名方面,我希望尽可能具体.如果你有一个名为'utils'的包含20个类,请将StringUtils移动到support/string,HttpUtil移动支持/ http等等.


Ste*_*n C 12

是否有关于Java程序包组织的最佳实践以及它们的内容?

不是真的没有.有很多想法和很多意见,但"最佳实践"是使用你的常识!

但是,有一个原则可能已被广泛接受.您的包结构应该反映您的应用程序的(非正式)模块结构,您应该尽量减少(或理想地完全避免)模块之间的任何循环依赖.

(包/模块中的类之间的循环依赖关系很好,但是包之间的循环往往会使您难以理解应用程序的体系结构,并且可能成为代码重用的障碍.特别是,如果您使用Maven,您会发现循环包间/模块间依赖性意味着整个互连的混乱必须是一个Maven工件.)

我还要补充一点,那里一个包名广为接受的最佳实践.这就是您的软件包名称应以相反的顺序从您组织的域名开始.如果您遵循此规则,则可以降低因(完整)类名与其他人发生冲突而导致问题的可能性.


Vol*_*man 7

我见过有人提倡“按功能打包”而不是“按层打包”,但是多年来我使用了很多方法,发现“按层打包”比“按功能打包”要好得多。

除此之外,我发现一种混合策略:“按模块打包,然后按要素打包”策略在实践中效果非常好,因为它具有“按要素打包”的许多优点:

  • 促进可重用框架(具有模型和UI方面的库)的创建
  • 允许即插即用的层实现-对于“按功能打包”几乎是不可能的,因为它将层实现放置在与模型代码相同的包/目录中。
  • 还有很多...

我在这里详细解释:Java包名称的结构和组织但是我的标准包结构是:

revdomain.moduleType.moduleName.layer。[layerImpl] .feature.subfeatureN.subfeatureN + 1 ...

哪里:

revdomain反向域,例如com.mycompany

moduleType [app * | framework | util]

moduleName例如myAppName(如果模块类型为应用程序)或“财务”(如果其为记帐框架)

[模型| ui |持久性|安全性等,]

layerImpl,例如,wicket,jsp,jpa,jdo,hibernate(注意:如果图层是模型则不使用)

功能,例如财务

子功能N,例如会计

子功能N + 1,例如折旧

*有时,如果moduleType是应用程序,则省略“ app”,但是将其放置在其中会使包结构在所有模块类型之间保持一致。


Bri*_*n S 6

我不知道包组织的标准做法。我通常会创建涵盖一些相当广泛的范围的包,但我可以在一个项目中进行区分。例如,我目前正在处理的一个个人项目有一个专门用于我的自定义 UI 控件的包(充满了从 Swing 类继承的类)。我有一个专门用于我的数据库管理内容的包,我有一个用于我创建的一组侦听器/事件的包,等等。

另一方面,我让一位同事为他所做的几乎所有事情创建了一个新包。他想要的每个不同的 MVC 都有自己的包,而且 MVC 集似乎是唯一允许在同一个包中的类分组。我记得有一次他有 5 个不同的包,每个包都有一个类。我认为他的方法有点极端(当我们根本无法处理时,团队强迫他减少他的包数),但对于一个重要的应用程序,将所有内容放在同一个包中也是如此。这是您和您的队友必须为自己找到的平衡点。

您可以做的一件事是尝试退后一步思考:如果您是项目的新成员,或者您的项目以开源或 API 的形式发布,那么找到您想要的东西有多么容易/困难?因为对我来说,这就是我真正想要的包:组织。与我在计算机上的文件夹中存储文件的方式类似,我希望能够再次找到它们,而无需搜索我的整个驱动器。我希望能够找到我想要的类,而不必搜索包中所有类的列表。