
How should I structure a Java application, where do I put my classes?首先,我知道如何构建Java应用程序。 但是我总是对在哪里上课感到困惑。 支持以严格面向领域的方式组织软件包的支持者,其他支持者则按层分开。 我本人一直有问题
所以, 我真的很喜欢Maven的标准目录布局。 对我来说,关键思想之一是拥有两个源根-一个用于生产代码,一个用于测试代码,如下所示:
(在这里,src / main / java和src / test / java都是源根)。 好处:
关于类放置和包的一条经验法则: 一般来说,结构良好的项目将没有循环依赖。了解何时它们不好(什么时候不好),并考虑使用诸如JDepend或SonarJ之类的工具来帮助您消除它们。 我非常喜欢有组织的资源,因此我总是创建以下目录结构:
在/ src中,我使用默认的Java模式:以您的域开头的包名称(org.yourdomain.yourprojectname)和反映您正在使用该类创建的OOP方面的类名称(请参见其他注释器)。诸如util,model,view,events之类的通用软件包名称也很有用。 我倾向于将特定主题的常量放在自己的类中,例如SessionConstants或ServiceConstants在同一个域类包中。
在我工作的地方,我们使用的是Maven 2,我们的项目有一个很好的原型。目标是获得良好的关注点分离,因此我们使用多个模块(每个应用程序"层"一个)定义了一个项目结构: 每个模块都有其自己的依赖项(例如,存储库可以具有jpa),并且某些模块是项目范围的(因此它们属于公共模块)。不同项目模块之间的依赖关系清楚地将事物分开(例如,Web层取决于服务层,但不知道存储库层)。 每个模块都有其自己的基本包,例如,如果应用程序包为" com.foo.bar",则我们具有:
每个模块都遵循标准的maven项目结构:
给定层的单元测试可以很容易地在\ src \ test下找到它们的位置。所有特定于领域的东西都位于实体模块中。现在,应该将诸如FileStorageStrategy之类的内容放入存储库模块中,因为我们不需要确切地知道实现是什么。在服务层,我们只知道存储库接口,我们不在乎具体的实现是什么(关注点分离)。 这种方法有多个优点:
我知道这并不能回答您的所有问题,但是我认为这可以使您走上正确的道路,并可能对其他人有用。 类名应始终是描述性的,并且不言自明。如果您对类负责多个领域,则应该将其重构。 对于您的包裹也是如此。它们应按责任范围分组。每个域都有其自己的例外。 通常不要流汗,直到它变得势不可挡和肿胀为止。然后坐下来,不编写代码,只重构类,定期编译以确保一切正常。然后像以前一样继续。 简短的答案:根据模块并排绘制您的系统架构,每个模块垂直切成层(例如视图,模型,持久性)。然后使用类似com.mycompany.myapp.somemodule.somelayer的结构,例如com.mycompany.myapp.client.view或com.mycompany.myapp.server.model。 在老式的计算机科学模块化编程意义上,将顶层软件包用于应用程序模块应该是显而易见的。但是,在我从事的大多数项目中,我们最终都忘记了这样做,并且最终导致一堆没有该顶层结构的软件包。这种反模式通常将自己显示为"侦听器"或"动作"之类的程序包,这些程序将原本无关的类分组,仅仅是因为它们碰巧实现了相同的接口。 在模块内或在小型应用程序中,将包用于应用程序层。根据体系结构,可能的软件包包括以下内容:
在这些层的每一层中,如果有很多,按类型对类进行分组是很自然的。此处常见的反模式是不必要地引入过多的包和子包级别,以便每个包中只有几个类。 我发现对单元测试非常有用的一件事是拥有一个myApp / src /目录以及myApp / test_src /目录。这样,我可以将单元测试和它们测试的类放在相同的包中,但是当我准备生产安装时,可以轻松排除测试用例。 使用软件包将相关功能分组在一起。
通常,包树的顶部是域名的反向名称(
异常通常与引发它们的类放在同一个包中,因此,如果有 并没有真正的标准,只是使用常识,如果一切都太混乱了,那就重构吧! 我想保持简单,不要过度思考。不要过度抽象和过多分层。只要保持整洁,随着它的增长,对其进行重构就变得微不足道了。 IDE的最佳功能之一就是重构,所以为什么不使用它并为解决与应用程序相关的问题(而不是像代码组织这样的元问题)节省您的脑力。 我喜欢将我的课程分解为相互关联的软件包。
例如: 查看符合您所见内容的课程 控制核心功能类 实用任何杂项。使用的类(通常是静态函数) 等等
过去我做过的一件事-如果我要扩展课程,我将尝试遵循他们的约定。例如,当使用Spring Framework时,我会将MVC控制器类放在名为com.mydomain.myapp.web.servlet.mvc的程序包中 |