按功能打包方法是否良好?[已关闭]

2022-08-31 17:00:44

最近,我偶然发现了这个javalobby帖子,http://java.dzone.com/articles/how-changing-java-package 按功能打包java代码。

我喜欢这个想法,但我对这种方法几乎没有问题。我问了我的问题,但没有得到满意的答复。我希望StackOverflow上的某人可以澄清我的问题。

我喜欢按功能打包的想法,它大大减少了在编码时在包之间移动的时间,所有相关的东西都将在一个地方(包)。但是,不同包中的服务之间的交互呢?

假设我们正在构建一个博客应用程序,并且我们将所有与用户相关的操作(控制器/服务/存储库)放在包中。以及所有博客文章相关的操作(控制器/服务/存储库)在包中。com.mycompany.myblog.userscom.mycompany.myblog.posts

现在我想显示用户配置文件以及他发布的所有帖子。我应该从 中拨打电话吗?myblog.posts.PostsService.getPostsByUser(userId)myblog.users.UserController.showUserProfile()

封装之间的耦合情况如何?

此外,无论我在哪里读到有关按功能打包的信息,每个人都说这是一个很好的做法。那么,为什么许多书籍作者甚至框架都鼓励按层分组呢?只是好奇知道:-)


答案 1

看看鲍勃叔叔的包装设计原则。他解释了这些原则背后的原因和动机,我在下面详细阐述了这些原则:

一起重用的类应该打包在一起,以便可以将包视为可供您使用的完整产品。那些一起重复使用的应该与那些没有被重用的分开。例如,日志记录实用程序类不一定与文件 io 类一起使用。因此,请单独打包所有日志记录它们。但是日志记录类可以彼此相关。因此,创建一种用于日志记录的完整产品,例如,为了需要更好的名称commons-logging包,将其放在一个(可重用的jar)中,以及另一个用于io实用程序的单独完整产品中,再次用于需要更好的名称,例如commons-io.jar。如果你更新说commons-io库说支持java nio,那么你可能不一定想对日志记录库进行任何更改。因此,将它们分开会更好。

现在,假设您希望您的日志记录实用程序类支持结构化日志记录,例如通过splunk等工具进行某种日志分析。您的日志记录实用程序的某些客户端可能希望更新到较新版本;其他一些可能没有。因此,当您发布新版本时,请将迁移所需的所有类打包在一起并重用。因此,您的实用程序类的某些客户端可以安全地删除旧的 commons-logging jar 并移动到 commons-logging-new jar。其他一些客户端仍然可以使用较旧的jar。但是,不需要客户端同时拥有这两个 jar(新旧),只是因为您强制它们对较旧的打包 jar 使用某些类。

避免循环依赖关系。a 取决于 b;b on c;c on d;但 d 取决于 a。这种情况显然是令人望而却步的,因为很难定义层或模块等,并且您无法相互独立地改变它们。

此外,您可以打包类,以便在层或模块发生更改时,其他模块或层不必更改。因此,例如,如果您决定从旧的MVC框架升级到其余API升级,那么只有视图和控制器可能需要更改;您的模型没有。


答案 2

我个人喜欢“按功能打包”的方法,尽管您确实需要对绘制包边界的位置应用相当多的判断。在许多情况下,这当然是一种可行且明智的方法。

您可能应该使用公共接口实现包和模块之间的耦合 - 这保持了耦合的干净和可管理性。

对于“博客文章”包来说,调用“用户”包是完全可以的,只要它使用精心设计的公共接口来执行此操作。

不过,如果你采用这种方法,有一个很大的建议是:要非常仔细地考虑你的依赖关系,特别是避免包之间的循环依赖关系。一个好的设计应该看起来像一个依赖树 - 具有更高级别的功能区域,这取决于一组依赖于实用程序函数库等的公共服务。在某种程度上,这将开始看起来像架构“层”,前端包调用后端服务。


推荐