首先,我知道如何构建一个Java应用程序。但我一直很困惑该把课放在哪里。有些支持者以严格面向领域的方式组织包,其他人则按层分开。

我自己也一直有这样的问题

  • 命名,
  • 放置

所以,

  1. 您将域特定常量放在哪里(以及此类的最佳名称是什么)?
  2. 您将基础设施和特定领域的类放在哪里(例如我有一个 FileStorageStrategy 类,它将文件存储在数据库中,或者存储在数据库中)?
  3. 异常应该放在哪里?
  4. 有什么标准可以参考吗?
有帮助吗?

解决方案

我真的开始喜欢Maven了 标准目录布局.

对我来说,关键想法之一是拥有两个源代码根 - 一个用于生产代码,另一个用于测试代码,如下所示:

MyProject/src/main/java/com/acme/Widget.java
MyProject/src/test/java/com/acme/WidgetTest.java

(这里,src/main/java 和 src/test/java 都是源根)。

优点:

  • 您的测试具有对被测类的包(或“默认”)级别访问权限。
  • 通过将 src/test/java 作为源根目录,您可以轻松地将生产源仅打包到 JAR 中。

关于课程安排和课程包的一条经验法则:

一般来说,结构良好的项目不会 循环依赖. 。学习他们什么时候表现不好(以及什么时候他们表现不好) 不是),并考虑像这样的工具 J依赖 或者 声纳J 这将帮助您消除它们。

其他提示

我非常喜欢有组织的资源,所以我总是创建以下目录结构:

/src - for your packages & classes
/test - for unit tests
/docs - for documentation, generated and manually edited
/lib - 3rd party libraries
/etc - unrelated stuff
/bin (or /classes) - compiled classes, output of your compile
/dist - for distribution packages, hopefully auto generated by a build system

在 /src 中,我使用默认的 Java 模式:以您的域 (org.yourdomain.yourprojectname) 开头的包名称和反映您使用该类创建的 OOP 方面的类名称(请参阅其他评论者)。常见的包名称如 实用程序, 模型, 看法, 事件 也很有用。

我倾向于将特定主题的常量放在自己的类中,例如 会话常量 或者 服务常数 在域类的同一包中。

在我工作的地方,我们使用 Maven 2,并且我们的项目有一个非常好的原型。目标是获得良好的关注点分离,因此我们使用多个模块定义了一个项目结构(每个应用程序“层”一个):- 常见的:其他层(例如I18N)使用的常见代码 - 实体:域实体 - 存储库:该模块包含DAOS接口和实现-Services -Intf:服务的接口(例如,UserService,...) - 服务-IMPL:服务的实现(例如,UserviceImpl) - 网络:有关Web内容的所有内容(例如CSS,JSP,JSF页面,...) - WS:网页服务

每个模块都有自己的依赖项(例如,存储库可能有 jpa),有些是项目范围的(因此它们属于公共模块)。不同项目模块之间的依赖关系清楚地分开了事物(例如,Web 层依赖于服务层,但不知道存储库层)。

每个模块都有自己的基础包,例如如果应用程序包是“com.foo.bar”,那么我们有:

com.foo.bar.common
com.foo.bar.entities
com.foo.bar.repositories
com.foo.bar.services
com.foo.bar.services.impl
...

每个模块都遵循标准的 Maven 项目结构:

   src\
   ..main\java
     ...\resources
   ..test\java
     ...\resources

给定层的单元测试很容易在 \src est 下找到它们的位置...特定于域的所有内容都在实体模块中占有一席之地。现在像 FileStorageStrategy 这样的东西应该进入存储库模块,因为我们不需要确切地知道实现是什么。在服务层,我们只知道存储库接口,我们不关心具体实现是什么(关注点分离)。

这种方法有很多优点:

  • 明确的关注点分离
  • 每个模块都可以打包为 jar(或者 web 模块中的 war),因此可以更轻松地重用代码(例如,我们可以将模块安装在 Maven 存储库中,然后在另一个项目中重用它)
  • 项目各部分的最大独立性

我知道这并不能回答您的所有问题,但我认为这可以让您走上正确的道路,并且对其他人可能有用。

类名应该始终具有描述性且不言自明。如果您的类有多个责任域,那么它们可能应该被重构。

同样对于你的包裹。他们应该按职责范围进行分组。每个域都有它自己的例外。

一般来说,不要出汗,直到你变得难以承受和臃肿。然后坐下来,不要编码,只需重构类,定期编译以确保一切正常。然后像以前一样继续。

使用包将相关功能组合在一起。

通常你的包树的顶部是你的域名反转(com.domain.subdomain)以保证唯一性,然后通常会有一个适合您的应用程序的包。然后按相关领域细分,这样你的 FileStorageStrategy 可能会进去说, com.domain.subdomain.myapp.storage, ,然后可能有特定的实现/子类/无论什么 com.domain.subdomain.myapp.storage.filecom.domain.subdomain.myapp.storage.database. 。这些名字可能会很长,但是 import 将它们全部保留在文件顶部,IDE 也可以帮助管理它们。

异常通常与引发异常的类位于同一个包中,因此如果您有,比如说, FileStorageException 它将与以下内容放在同一个包中 FileStorageStrategy. 。同样,定义常量的接口也将位于同一个包中。

实际上并没有任何标准,只需使用常识,如果一切变得太混乱,请重构!

我发现对单元测试非常有帮助的一件事是拥有 myApp/src/ 和 myApp/test_src/ 目录。这样,我可以将单元测试放置在与它们测试的类相同的包中,而且在准备生产安装时可以轻松排除测试用例。

简短回答:根据模块绘制系统架构,并排绘制,每个模块垂直分成几层(例如视图、模型、持久性)。然后使用类似的结构 com.mycompany.myapp.somemodule.somelayer, ,例如 com.mycompany.myapp.client.view 或者 com.mycompany.myapp.server.model.

使用顶级包进行应用 模块, ,在老式的计算机科学意义上 模块化编程, ,应该是显而易见的。然而,在我参与过的大多数项目中,我们最终忘记了这样做,并且最终得到了一堆没有顶级结构的软件包。这种反模式通常将自己显示为“侦听器”或“操作”之类的包,这些包将其他不相关的类分组,仅仅是因为它们碰巧实现了相同的接口。

在模块内或小型应用程序中,对应用程序层使用包。可能的包包括如下内容,具体取决于架构:

  • com.mycompany.myapp.view
  • com.mycompany.myapp.model
  • com.mycompany.myapp.services
  • com.mycompany.myapp.rules
  • com.mycompany.myapp.persistence (或“dao”表示数据访问层)
  • com.mycompany.myapp.util (注意这个被当作“杂项”使用)

在每一层中,如果类很多,很自然地按类型对类进行分组。这里的一个常见的反模式是不必要地引入太多的包和子包级别,使得每个包中只有几个类。

我认为保持简单,不要想太多。不要过度抽象和分层。只要保持它整洁,随着它的增长,重构它是微不足道的。IDE 的最佳功能之一是重构,所以为什么不利用它来节省您的脑力来解决与应用程序相关的问题,而不是像代码组织这样的元问题。

我过去做过的一件事 - 如果我要扩展一门课程,我会尝试遵循他们的惯例。例如,在使用弹簧框架时,我将在一个名为com.mydomain.myapp.web.servlet.mvc的软件包中使用我的MVC控制器类。com.mydomain.domain 用于域对象(尽管如果您有大量域对象,这个包可能会有点笨拙)。对于特定于领域的常量,我实际上将它们作为公共常量放在最相关的类中。例如,如果我有一个“Member”类并且有一个最大成员名称长度常量,我将其放入 Member 类中。有些商店创建了一个单独的 Constants 类,但我没有看到将不相关的数字和字符串集中到一个类中的价值。我见过其他一些商店试图通过创建单独的常量类来解决这个问题,但这似乎是浪费时间,而且结果太混乱。使用此设置,具有多个开发人员的大型项目将在各处复制常量。

我喜欢将我的类分解成彼此相关的包。

例如:模型 对于数据库相关的调用

看法 处理你所看到的内容的类

控制 核心功能类

效用 任何杂项。使用的类(通常是静态函数)

ETC。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top