带有接口的 Spring 目录结构(最佳实践)

Tib*_*riu 4 java spring hibernate spring-boot

我目前正在编写我的第一个 Spring 应用程序(Spring boot + hibernate)。我在这里查看了他们文档中的最佳实践目录结构。这说得通。

问题 1:

我有一个interface(或Abstract class) 几个子类扩展,所以我只需要一个@Repository父类。我决定这样做:

com
 +- example
     +- myapplication
         +- Application.java
         |
         +- message
         |   +- AbstractMessage.java
         |   +- IMessageRepository.java
         |   +- MessageRepositoryImpl.java
                +- messageTypeA
                |  +- messageTypeA.java
                |  +- messageTypeAService.java
                +- messageTypeB
                |  +- messageTypeB.java
                |  +- messageTypeBService.java
Run Code Online (Sandbox Code Playgroud)

问题2:

现在我有一个新entity的保存名为Group. 所以我能做的就是添加一个GroupMessage. 但是,这Group实际上是Message(例如,逻辑上)的一部分,因此如果它属于同一message目录的一部分实际上是有意义的(我们将它们保存为不同实体的唯一原因是因为以这种方式导出分析更有意义)。此外,我什至使用相同的方法MessageRepository来保存它(我只是在界面中添加了第二种方法,如下所示:)

public interface MessageRepository {

    void insert(AbstractMessage message);

    void insert(AbstractMessage message, AbstractGroup group);
}
Run Code Online (Sandbox Code Playgroud)

像下面这样的东西会好吗?还是每个人 entity都应该有自己的包?我是不是想多了?

com
 +- example
     +- myapplication
         +- Application.java
         |
         +- message
         |   +- AbstractMessage.java
         |   +- IMessageRepository.java
         |   +- MessageRepositoryImpl.java
             |  +- messageTypeA
             |     +- messageTypeA.java
             |     +- messageTypeAService.java
             |  +- messageTypeB
             |     +- messageTypeB.java
             |     +- messageTypeBService.java
             |
             +- group
                +- AbstractGroup.java
                +- GroupTypeX.java // same service as message, just different entity
                +- GroupTypeY.java // same service as message, just different entity
Run Code Online (Sandbox Code Playgroud)

Lpp*_*Edd 6

这更多是基于意见的事情,但我想给你一些建议。

首先,命名。接口上
I前缀是 IBM 用于识别它们的“古老”技术。请不要这样做,这是多余的,在新鲜环境中没有意义。什么是I-MessageRepository?!
您会在Eclipse RCP项目或 IBM 的任何产品中发现这种命名约定。

然后是实现名称。不要使用Impl后缀,它不会对正在阅读或编辑您的代码的人说任何话。
给它一个名称,说明它的目的或域范围是什么。

ActiveMQMessageRepository
FileMessageRepository
TcpMessageRepository
Run Code Online (Sandbox Code Playgroud)

其次,Repositories
存储库应该管理单一类型的对象,而不是多个。使用Services协调多个Repositories。这样大家调试起来会更方便,而且会解耦很多代码。


第三,packages
尽量保持扁平的封装结构。扁平结构更易于维护、更易于查看、更易于理解。不要创建几十个子包,例如

- messages
   - services
       MessageService
     - implementations
        ...
   - repositories
       MessageRepository
     - abstract
         AbstractMessageRepository
     - implementations
         TextMessageRepository
   - exceptions
     - runtime
     - checked
         UnsupportedMessageException
Run Code Online (Sandbox Code Playgroud)

可怕又无用。并且您无法利用包可见性

因此,将messagesgroups放在单独的包上,并给它们自己的Repository.

从包中公开接口,而不是具体的实现。(如果可能)

  • @Tiberiu 当然,我的意思是接受单一类型的界面。这样可以更容易地保持您的存储库和服务尽可能小。更少的代码,更少的错误;) (2认同)