Spring 在服务中使用多个服务或多个存储库?

Spring 在服务中使用多个服务或多个存储库?,spring,spring-boot,spring-data,domain-driven-design,Spring,Spring Boot,Spring Data,Domain Driven Design,假设我们有两个实体,EntityA和EntityB。这两个实体都有一个用于查询数据库的存储库,EntityARepository和EntityBRepository。它们都有服务,EntityAService和EntityBService 现在,EntityBService中有一个方法,它也需要使用EntityA。这样做的正确方式是什么 EntityBService是否应直接使用EntityARepository EntityBService是否应该使用EntityAService 我可以看

假设我们有两个实体,
EntityA
EntityB
。这两个实体都有一个用于查询数据库的存储库,
EntityARepository
EntityBRepository
。它们都有服务,
EntityAService
EntityBService

现在,
EntityBService
中有一个方法,它也需要使用
EntityA
。这样做的正确方式是什么

  • EntityBService
    是否应直接使用
    EntityARepository
  • EntityBService
    是否应该使用
    EntityAService
我可以看出,直接使用存储库可能非常方便,但当它不仅有两个实体时,它似乎变得有点混乱

围绕此主题或建议是否有共同的设计模式?

TLDR;这要看情况了

如果您试图遵循域驱动设计,我认为区分
服务
存储库
是一个好主意。有不同的定义,可能在细节上有所不同,但我将坚持Martin Fowler的定义:

(…)存储库在域和数据映射层之间进行中介,就像内存中的域对象集合一样。(……)

以及:

服务层从接口客户端层的角度定义应用程序的边界[Cockburn PloP]及其可用操作集它封装了应用程序的业务逻辑,在实现其操作时控制事务并协调响应。

值得指出的是,
服务
不仅仅是
存储库
+业务逻辑。对于大多数简单场景,
repository
只需结束访问单个数据库,但对于高级场景,创建单个实体可能需要访问多个数据库,因此
repository
角色是从
服务
层删除此woffle

下面是你能想到的:

  • 如果您试图做的只是获取
    EntityA
    而没有任何与
    EntityA
    相关的业务逻辑,请直接在
    EntityBService
    中使用
    EntityA positiory
    。下面是一个简单的例子:
  • EntityBService
    EntityB
    执行操作,但它完全取决于
    EntityA
    状态

  • 如果请求
    EntityA
    涉及一些与
    EntityA
    相关的业务逻辑,请在
    EntityBService
    中使用
    EntityAService
    。下面是一个简单的例子:
  • EntityBService
    EntityB
    EntityA
    执行操作,如果不存在,则需要创建以后的服务-创建涉及业务逻辑,如检查是否允许(例如,基于用户角色)

    围绕这个主题或建议是否有共同的设计模式

    一种常见做法是避免更改存储在同一事务中不同位置的实体。确保从不这样做的一种方法是在任何事务中只有一个实体处于活动状态

    因此,我们可能合理地拥有entityA,以及我们需要从B获得的信息副本。或者我们可能拥有entityB,以及我们需要从a获得的信息副本

    对于不改变任何一个实体的用例,我们可以只使用数据的副本

    在使用
    entityA
    recent-copy-of-B
    的情况下,我们知道entityA来自存储库。
    B的最新副本
    来自哪里?嗯,它来自一个看起来像存储库的抽象,除了(a)它获取值,而不是实体和(b)它是只读的

    recent-copy-of-B
    看起来有点像DTO。尽管您可能在任何地方都使用相同的版本,但为不同的用例创建专门的版本实际上是安全的(因为值是不可变的)