我正在尝试不费吹灰之力实现完全有效的持久性无知。我有很多问题:

最简单的选项

这真的很简单-是否可以像在SOA中那样用Spring Data注释对Entries进行注释(但是让它们真正地执行逻辑)?除了不必在实体中真正使用PI原理的实体中使用持久性注释外,还有什么后果?我的意思是Spring Data确实是这种情况-它提供了不错的存储库,可以完成DDD中的存储库应做的事情。问题在于实体本身……

较难的选项

为了使实体不知道其操作的数据来自何处,自然可以通过构造函数将该数据作为接口注入。另一个优点是,我们总是可以执行延迟加载-例如,默认情况下,我们在Neo4j图形数据库中具有延迟加载。缺点是,聚合(由实体组成)即使不使用它们也会完全了解所有数据-可能会由于数据完全暴露而导致调试困难(DAO就像聚合一样,是分层的)。这也将迫使我们对存储库使用某些适配器,因为它们不再存储真实的实体了。而且任何转换都是丑陋的。另一件事是,如果没有这样的DAO,我们无法实例化一个Entity-尽管可能存在领域中的内存实现...再次,更多层。有人说注入DAO也会破坏PI。

最难的选项

实体可以包裹在一个懒惰加载器周围,后者决定数据应该来自哪里。它既可以在内存中,也可以在数据库中,并且可以处理任何需要事务处理的操作等等。虽然很复杂,但是在某种程度上可能是通用的……?阅读有关here

您知道其他解决方案吗?或者也许我在提到的东西中缺少了一些东西。请分享您的想法!

最佳答案

作为适当的域建模的副作用,我(几乎)免费获得了持久性无知。

特别是:

  • 如果正确定义每个上下文的边界,则无需延迟加载即可获得小实体(在DDD项目中实际上变成了反模式/代码气味)
  • (如果您不能简单地在存储库中使用SQL),将一组DTO映射到您的数据库模式,然后将它们用于工厂中以初始化实体类。

  • 在DDD项目中,持久性无知与域模型本身有关,而与存储库,工厂和其他应用程序代码无关。实际上,您将来不太可能更改ORM和/或数据库。

    域模型的持久性无知背后的(但非常强大)理性是关注点分离:在域模型中,您应该仅表示来表示业务变量!持久性是基础设施问题!

    例如,在没有持久性忽略的情况下(以及延迟加载的情况下),域模型应该处理数据库中可能出现的异常,它的复杂性会增加,并且业务规则会被技术细节所掩盖。

    07-24 22:24