如何使用 Spring Crud/Jpa Repository 实现 DDD

2024-05-18

我想通过使用 Spring 实现 DDD 来创建一个应用程序。假设我有一个业务实体 Customer 和一个接口 CustomerRepository。

由于春天提供了CrudRepository and JpaRepository默认情况下,要执行基本的 CRUD 操作和其他操作(如查找方法),我想使用它们。所以我的界面变成了

 @Repository
public interface CustomerRepository extends JpaRepository<Customer, Long>{

}

但根据DDD,接口应该在领域层,实现应该在基础设施层。

现在我的问题是,CustomerRepository 属于哪一层?


简短回答:尽管它应该是域层中基础设施的任何依赖项,但为了KISS https://en.wikipedia.org/wiki/KISS_principle, you may这样做。如果你想成为 DDD 纯粹主义者,你可以定义一个CustomerRepository接口以及基础设施中实现这两个接口的实现。

又长又无聊的答案:一般来说,域不应该关心或了解基础设施,因为它不应该依赖于其他层(基础设施、应用程序、表示或您正在使用的任何体系结构)。遵循这条规则会产生更干净的架构。

特别是,域不应该关心持久性,它的行为应该像在内存中运行一样。从领域的角度来看,实体会发生变异,仅此而已,不需要持久性。

域代码的写入端实际上不需要持久性。当聚合执行命令时,它们已经完全加载。执行命令后,聚合仅返回更改或新状态。聚合本身并不保留更改。它们是纯净的,没有明显的副作用。

我们,架构师,需要持久性,因为我们需要确保数据在重新启动之间保持不变,并且我们可以同时在多台机器上运行相同的代码。

然而,域代码还有另一个需求,特别是域的读取和响应端(Sagas/进程管理器)。域的这些组件需要查询和过滤域实体。 Readmodels 需要将实体返回给调用者,Sagas/Process 管理器需要正确识别向其发送命令的正确聚合。

解决方案是仅在域层中定义接口并在基础设施中实现。通过这种方式,域拥有接口,因此,根据依赖倒置原则 https://en.wikipedia.org/wiki/Dependency_inversion_principle,它不依赖于基础设施。

在你的情况下,虽然域层取决于某物从 Spring 框架的基础设施部分来看,某物只是一个接口。它仍然是对 JPA 的依赖,因为您的域将使用它不拥有的方法,但在这种情况下 KISS 可能更重要。

另一种方法是定义一个不扩展 JpaRepository 的接口,并在基础设施中实现该接口和 JpaRepository 接口。

哪种解决方案取决于您:更多代码重复但更少依赖,或者更少代码重复但更多对 JPA 的依赖。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 Spring Crud/Jpa Repository 实现 DDD 的相关文章

随机推荐

  • HTML5 仅拖放图像

    我想做的是 如果所有拖动的文件都是图像 则将其删除 但如果有其他文件扩展名 则不要删除它们 而仅删除图像 这是我的尝试 HTML div div JavaScript var dropzone document getElementById
  • 在 Laravel 中动态设置数据库连接和语言

    我有 3 个域指向同一个Laravel应用 我想要的是每个人都连接到自己的数据库并根据 TLD 加载自己的语言文件 我可以在哪个文件中设置这些设置 我可以直接在配置文件中执行此操作 或者可以在加载配置之前执行某些事件 我拥有的是一个简短的函
  • web3.eth.sendSignedTransaction() 总是返回“返回错误:nonce 太低”

    I used 电子邮件受保护 cdn cgi l email protection在 Node js 中与私有区块链交互 我是按照官方文档写的代码 电子邮件受保护 cdn cgi l email protection var Web3 re
  • Rails/Ruby 合并两个具有相同键、不同值的哈希值

    我有两个想要合并的哈希值 它们看起来像这样 Hello gt 3 Hi gt 43 Hola gt 43 第二个哈希看起来像 Hello gt 4 Hi gt 2 Bonjour gt 2 我想合并这两个哈希数组 使结果看起来像 Hello
  • 为什么Boost的`bcp smart_ptr dir/`复制了6MB的源代码?

    所以我想从 boost 中分离出智能指针来在我的项目中使用 并且我被引导使用bcp公用事业 今天我把它编译并做了bcp smart ptr to copy to my project 结果 6MB 代码to copy to my proje
  • Arbor Js - 节点 Onclick?

    我在用着arbor js http arborjs org 创建图表 我如何创建一个onclick节点的事件 或者在单击时在某处创建节点链接 Arborjs org 主页的节点在单击时链接到外部页面 我如何复制它 或者使节点在单击时调用 j
  • 在带有 Storyboard 的 XCode 4 中以模态方式推送视图时,出现“对开始/结束外观转换的不平衡调用”警告

    在网上进行了一些研究但没有成功后 我来这里向您询问有关我的警告的问题 实际上 我有一个带有导航控制器的视图 V1 我想在 V1 完成加载时推送模态视图 V2 所以我用performSegueWithIdentifier方法 我正在使用故事板
  • C# 接收和发送数据

    我仍在努力改进我之前写的东西 现在我在接收数据时遇到了问题 我有一个程序 用于使用 tcpClient 将字符串发送到正在侦听指定端口的程序 它工作正常 所以我决定再发送一次数据 public static void receiveThre
  • 使用数据库中的项目填充复选框列表?

    好的 所以我想将一些数据填充 绑定到复选框列表 但似乎无法绑定正确的值 我想用 ROW 中的信息填充它 而不是我所发生的整个列 无论如何 这里有一些代码可以向您展示问题所在 这是xaml中的代码
  • 验证/操作多租户 Web API 中的输入参数

    假设我们有一个多租户博客应用程序 该应用程序的每个用户可能拥有多个由该服务托管的博客 我们的 API 允许读取和写入博客文章 在某些情况下 指定 BlogId 是可选的 例如 获取用 ASP NET 标记的所有帖子 api posts ta
  • 如何将 kubectl 配置文件与 ~/.kube/config 合并?

    有没有一个简单的kubectl命令采取kubeconfig文件 包含 cluster context user 并将其合并到 kube config 文件作为附加上下文 Do this export KUBECONFIG kube conf
  • matlab中更快的插值方法

    我正在使用 interp1 来插值一些数据 temp 4 30 4 rand 365 10 depth 1 10 dz 0 5 define new depth interval bthD min depth dz max depth ne
  • 更改 3D 图形颜色 (matplotlib)

    我使用以下代码在 matplotlib 中绘制了 3D 图形 Previously defines lists of data to plot fig plt figure ax fig add subplot 111 projection
  • Redux - 从函数调用操作

    我正在尝试从函数调用 redux 操作 我调用该函数的组件已连接到商店 但是 如果我通过以下操作 它就不起作用 function myFunc action action 有没有办法通过参数传递动作 谢谢 using bindActionC
  • 从 arraylist 和 hashmap 中删除重复项

    我有一个数组列表 其中包含付款人的姓名 另一个数组列表包含每次付款的费用 例如 nameArray 尼古拉 劳尔 洛伦佐 劳尔 劳尔 洛伦佐 尼古拉 价格数组 24 12 22 18 5 8 1 我需要将每个人的费用相加 所以数组必须变成
  • 如何用C++实现自然排序算法?

    我正在对由文本和数字组成的字符串进行排序 我希望排序将数字部分排序为数字 而不是字母数字 例如我想要 abc1def abc9def abc10def 而不是 abc10def abc1def abc9def 有谁知道这个的算法 特别是在c
  • p2p 通信中的对等方如何相互验证?

    WebRTC 中的对等点如何相互验证 WebRTC 中的 DTLS 使用自签名证书 RFC 5763 https www rfc editor org rfc rfc5763具有详细信息 简而言之 证书指纹与 SDP 的 a fingerp
  • 跟踪循环迭代

    抛硬币 成功 你赢100 否则你输50 你会一直玩 直到你口袋里有钱a 的价值如何a在任何迭代中都被存储 a lt 100 while a gt 0 if rbinom 1 1 0 5 1 a lt a 100 else a lt a 50
  • Java .drawImage:如何“取消绘制”或删除图像?

    我需要在程序运行时不断在不同位置重绘某个图像 因此 我设置了一个 while 循环 该循环应该在屏幕上移动图像 但它只是一遍又一遍地重新绘制图像 我究竟做错了什么 有没有办法在将旧图像绘制到新位置之前删除旧图像 JFrame frame b
  • 如何使用 Spring Crud/Jpa Repository 实现 DDD

    我想通过使用 Spring 实现 DDD 来创建一个应用程序 假设我有一个业务实体 Customer 和一个接口 CustomerRepository 由于春天提供了CrudRepository and JpaRepository默认情况下