您在Java项目中使用什么策略进行包命名?为什么? [英] What strategy do you use for package naming in Java projects and why?

查看:106
本文介绍了您在Java项目中使用什么策略进行包命名?为什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前想过这个问题,最近我的商店正在开发第一个真正的Java网络应用程序。

I thought about this awhile ago and it recently resurfaced as my shop is doing its first real Java web app.

作为介绍,我看到两个主要的包命名策略。 (要清楚,我不是指整个'domain.company.project'的一部分,我正在谈论它下面的包约定。)无论如何,我看到的包命名约定如下: / p>

As an intro, I see two main package naming strategies. (To be clear, I'm not referring to the whole 'domain.company.project' part of this, I'm talking about the package convention beneath that.) Anyway, the package naming conventions that I see are as follows:


  1. 功能:根据业务领域,根据其功能在架构上命名您的软件包而不是其身份。另一个术语可能是根据'layer'命名。所以,你有一个* .ui包和一个* .domain包和一个* .orm包。你的包是水平切片而不是垂直切片。

  1. Functional: Naming your packages according to their function architecturally rather than their identity according to the business domain. Another term for this might be naming according to 'layer'. So, you'd have a *.ui package and a *.domain package and a *.orm package. Your packages are horizontal slices rather than vertical.

这比逻辑命名更常见 。事实上,我不相信我曾经见过或听说过这样做的项目。这当然让我很冷静(有点像认为你已经想出了NP问题的解决方案),因为我不是非常聪明,我认为每个人都必须有充分的理由按照他们的方式去做。另一方面,我并不反对人们只是在房间里错过了大象我从来没有听说过的实际论据以这种方式进行包命名。它似乎只是事实上的标准。

This is much more common than logical naming. In fact, I don't believe I've ever seen or heard of a project that does this. This of course makes me leery (sort of like thinking that you've come up with a solution to an NP problem) as I'm not terribly smart and I assume everyone must have great reasons for doing it the way they do. On the other hand, I'm not opposed to people just missing the elephant in the room and I've never heard a an actual argument for doing package naming this way. It just seems to be the de facto standard.

逻辑:根据业务领域标识命名您的软件包并放入每个类这与包中的垂直功能有关。

Logical: Naming your packages according to their business domain identity and putting every class that has to do with that vertical slice of functionality into that package.

我从未见过或听说过这个,正如我之前提到的那样,但它有很多意义对我来说。

I have never seen or heard of this, as I mentioned before, but it makes a ton of sense to me.


  1. 我倾向于垂直接近系统而不是水平接近系统。我想进入并开发订单处理系统,而不是数据访问层。显然,我很有可能在该系统的开发中触及数据访问层,但重点是我不这么认为。当然,这意味着当我收到变更单或者想要实现一些新功能时,不必为了找到所有相关的类而不必在一堆包中钓鱼。相反,我只是查看X包,因为我正在做的事情与X有关。

  1. I tend to approach systems vertically rather than horizontally. I want to go in and develop the Order Processing system, not the data access layer. Obviously, there's a good chance that I'll touch the data access layer in the development of that system, but the point is that I don't think of it that way. What this means, of course, is that when I receive a change order or want to implement some new feature, it'd be nice to not have to go fishing around in a bunch of packages in order to find all the related classes. Instead, I just look in the X package because what I'm doing has to do with X.

从开发的角度来看,我认为它是一个主要的赢得让您的包记录您的业务领域而不是您的架构。我觉得这个领域几乎总是系统的一部分,因为系统的体系结构,特别是在这一点上,它的实现几乎变得平凡,因此很难理解。事实上,我可以通过这种类型的命名约定来到一个系统,并立即从包的命名知道它处理订单,客户,企业,产品等似乎非常方便。

From a development standpoint, I see it as a major win to have your packages document your business domain rather than your architecture. I feel like the domain is almost always the part of the system that's harder to grok where as the system's architecture, especially at this point, is almost becoming mundane in its implementation. The fact that I can come to a system with this type of naming convention and instantly from the naming of the packages know that it deals with orders, customers, enterprises, products, etc. seems pretty darn handy.

这似乎可以让您更好地利用Java的访问修饰符。这使您可以更清晰地将接口定义到子系统中,而不是定义到系统的各个层中。因此,如果你有一个你希望透明持久的订单子系统,理论上你永远不会让任何其他东西知道它是持久的,因为不必在dao层中为其持久化类创建公共接口,而是将dao类包装在只有它处理的类。显然,如果您希望公开此功能,您可以为其提供界面或将其公开。通过将系统功能的垂直切片分成多个包,您似乎失去了很多。

It seems like this would allow you to take much better advantage of Java's access modifiers. This allows you to much more cleanly define interfaces into subsystems rather than into layers of the system. So if you have an orders subsystem that you want to be transparently persistent, you could in theory just never let anything else know that it's persistent by not having to create public interfaces to its persistence classes in the dao layer and instead packaging the dao class in with only the classes it deals with. Obviously, if you wanted to expose this functionality, you could provide an interface for it or make it public. It just seems like you lose a lot of this by having a vertical slice of your system's features split across multiple packages.

我认为我可以看到一个缺点是它确实使得剥离层更加困难。您必须进入并更改所有软件包中的所有类,而不是仅删除或重命名软件包,然后使用备用技术删除新软件包。但是,我不认为这是一个大问题。这可能源于缺乏经验,但我必须想象,与您进入并编辑系统中垂直特征切片的次数相比,您更换技术的次数相形见绌。

I suppose one disadvantage that I can see is that it does make ripping out layers a little bit more difficult. Instead of just deleting or renaming a package and then dropping a new one in place with an alternate technology, you have to go in and change all of the classes in all of the packages. However, I don't see this is a big deal. It may be from a lack of experience, but I have to imagine that the amount of times you swap out technologies pales in comparison to the amount of times you go in and edit vertical feature slices within your system.


所以我想那个问题会告诉你,你如何命名你的包裹为什么?请理解我并不一定认为我偶然发现了金鹅或其中的东西。我对这一切都很陌生,主要是学术经历。但是,我无法发现我的推理中的漏洞所以我希望你们都可以继续前进。

So I guess the question then would go out to you, how do you name your packages and why? Please understand that I don't necessarily think that I've stumbled onto the golden goose or something here. I'm pretty new to all this with mostly academic experience. However, I can't spot the holes in my reasoning so I'm hoping you all can so that I can move on.

推荐答案

对于包装设计,我首先按层,然后通过其他一些功能。

For package design, I first divide by layer, then by some other functionality.

还有一些额外的规则:


  1. 图层从最常见(底部)到最具体(顶部)堆叠

  2. 每个图层都有一个公共接口(抽象)

  3. 一个图层只能依赖于另一个图层的公共接口(封装)

  4. 一个图层只能依赖于更一般的图层(从上到下的依赖关系)

  5. 一个图层最好取决于它下面的图层

  1. layers are stacked from most general (bottom) to most specific (top)
  2. each layer has a public interface (abstraction)
  3. a layer can only depend on the public interface of another layer (encapsulation)
  4. a layer can only depend on more general layers (dependencies from top to bottom)
  5. a layer preferably depends on the layer directly below it

因此,对于一个Web应用程序来说例如,您可以在应用程序层中拥有以下图层(从上到下):

So, for a web application for example, you could have the following layers in your application tier (from top to bottom):


  • 表示层:生成将要显示的UI显示在客户端层

  • 应用层:包含ns特定于应用程序的逻辑,有状态

  • 服务层:按域分组功能,无状态

  • 集成层:提供对后端层的访问(db,jms,email,...)

  • presentation layer: generates the UI that will be shown in the client tier
  • application layer: contains logic that is specific to an application, stateful
  • service layer: groups functionality by domain, stateless
  • integration layer: provides access to the backend tier (db, jms, email, ...)

对于生成的包布局,这些是一些额外的规则:

For the resulting package layout, these are some additional rules:


  • 每个包名的根目录是< prefix.company>。< appname>。< layer>

  • 图层的界面按功能进一步拆分:< root>。< logic>

  • 图层的私有实现以private为前缀:< root> .private

  • the root of every package name is <prefix.company>.<appname>.<layer>
  • the interface of a layer is further split up by functionality: <root>.<logic>
  • the private implementation of a layer is prefixed with private: <root>.private

这是一个示例布局。

表示层按视图技术划分,可选择按(组)划分应用程序。

The presentation layer is divided by view technology, and optionally by (groups of) applications.

com.company.appname.presentation.internal
com.company.appname.presentation.springmvc.product
com.company.appname.presentation.servlet
...

应用程序层分为用例。

com.company.appname.application.lookupproduct
com.company.appname.application.internal.lookupproduct
com.company.appname.application.editclient
com.company.appname.application.internal.editclient
...

服务层分为业务域,受后端层中域逻辑的影响。

The service layer is divided into business domains, influenced by the domain logic in a backend tier.

com.company.appname.service.clientservice
com.company.appname.service.internal.jmsclientservice
com.company.appname.service.internal.xmlclientservice
com.company.appname.service.productservice
...

整合层分为技术和访问对象。

The integration layer is divided into 'technologies' and access objects.

com.company.appname.integration.jmsgateway
com.company.appname.integration.internal.mqjmsgateway
com.company.appname.integration.productdao
com.company.appname.integration.internal.dbproductdao
com.company.appname.integration.internal.mockproductdao
...

分离这样的包的好处是它更容易管理复杂性,并且它提高了可测试性和可重用性。虽然看起来很多开销,但根据我的经验,它实际上是非常自然的,并且每个人都在这个结构(或类似的)上工作,在几天内就可以完成。

Advantages of separating packages like this is that it is easier to manage complexity, and it increases testability and reusability. While it seems like a lot of overhead, in my experience it actually comes very natural and everyone working on this structure (or similar) picks it up in a matter of days.

为什么我认为垂直方法不太好?

Why do I think the vertical approach is not so good?

在分层模型中,几个不同的高级模块可以使用相同的低级模块。例如:您可以为同一个应用程序构建多个视图,多个应用程序可以使用相同的服务,多个服务可以使用相同的网关。这里的诀窍是,当移动层时,功能级别会发生变化。更具体的层中的模块不会在更一般的层上映射模块上的1-1,因为它们表达的功能级别不会映射1-1。

In the layered model, several different high-level modules can use the same lower-level module. For example: you can build multiple views for the same application, multiple applications can use the same service, multiple services can use the same gateway. The trick here is that when moving through the layers, the level of functionality changes. Modules in more specific layers don't map 1-1 on modules from the more general layer, because the levels of functionality they express don't map 1-1.

当您使用垂直方法进行包设计时,即首先按功能划分,然后将所有具有不同级别功能的构建块强制插入到相同的功能夹克中。您可以为更具体的模块设计通用模块。但这违反了更普遍的层不应该知道更具体的层的重要原则。例如,服务层不应该在应用层的概念之后建模。

When you use the vertical approach for package design, i.e. you divide by functionality first, then you force all building blocks with different levels of functionality into the same 'functionality jacket'. You might design your general modules for the more specific one. But this violates the important principle that the more general layer should not know about more specific layers. The service layer for example shouldn't be modeled after concepts from the application layer.

这篇关于您在Java项目中使用什么策略进行包命名?为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆