DDD 持久化模型与领域模型

我正在努力学习领域驱动设计(DDD) ,我想我已经有了基本的想法。但是有些事情让我很困惑。

在 DDD 中,持久性模型和领域模型是不同的吗?我的意思是,我们在设计领域和类时只考虑领域问题,这没有关系。但在此之后,当我们构建存储库或任何其他数据持久性系统时,我们是否应该创建模型的另一种表示以在持久性层中使用?

我认为我们的域模型也用于持久化,这意味着我们的存储库从查询中返回我们的域对象。但是今天,我读了这篇文章,我有点困惑:

别说了! 领域模型不是持久模型

如果这是真的,那么拥有独立于域对象的持久性对象的好处是什么呢?

31075 次浏览

在 DDD 中,持久性模型和领域模型是不同的吗?

是的,但是这并不一定意味着要显式地表示持久性模型的一组不同的类。

如果使用关系数据库来持久化,那么像 NHibernate 这样的 ORM 就可以通过映射到域类来表示持久化模型。在这种情况下,没有显式的持久化模型类。这种方法的成功取决于 ORM 的映射能力。例如,NHibernate 可以通过 成分映射支持中间映射类。这允许在需要时使用显式的持久性模型类。

如果使用文档数据库进行持久化,通常对持久化模型的需求就更少了,因为域模型只需要可序列化就可以持久化。

因此,当存在无法通过 ORM 映射到域模型来获得的复杂映射时,使用显式持久化模型类。无论实现如何,域模型和持久性模型之间的区别仍然存在。

这样想一下,域模型应该不依赖于任何东西,并且其中没有基础结构代码。域模型不应该是可序列化的,也不应该从某些 ORM 对象继承,甚至不应该共享它们。这些都是基础设施问题,应该与域模型分开定义。

但是,如果您正在寻找纯 DDD,并且您的项目重视可伸缩性和性能,而不是初始开发的速度,那么就需要这样做。很多时候,将基础设施问题与您的“域模型”混合在一起,可以帮助您以牺牲可伸缩性为代价在速度上取得巨大进步。关键是,您需要问自己,“在开发速度方面,纯 DDD 的好处是否值得付出代价?”.如果你的答案是肯定的,那么这就是你问题的答案。

让我们从一个示例开始,您的应用程序从一个域模型开始,恰好数据库中的表与您的域模型完全匹配。现在,您的应用程序突飞猛进,并且在查询数据库时开始遇到性能问题。您已经应用了一些经过深思熟虑的索引,但是表的增长速度非常快,似乎需要对数据库进行反规范化才能跟上。因此,在 dba 的帮助下,您提出了一种新的数据库设计,可以满足您的性能需求,但是现在的表与以前大不相同,现在您的域实体块分布在多个表中,而不是每个实体一个表。

这只是一个例子,但是它演示了为什么域模型应该与持久性模型分离。在这个示例中,您不希望拆分域模型的类来匹配您对持久化模型设计所做的更改,并从根本上改变域模型的含义。相反,您希望更改新的持久性模型和域模型之间的映射。

保持这些设计的独立性有几个好处,比如可伸缩性、性能和对紧急数据库更改的反应时间,但是您应该将它们与初始开发的成本和速度进行权衡。一般来说,从这种分离级别中获益最大的项目是大型企业应用程序。

评论员更新

在软件开发的世界中,有 N 个可能的解决方案。正因为如此,柔性与初始开发速度之间存在着间接的反向关系。作为一个简单的例子,我可以将逻辑硬编码到一个类中,也可以编写一个允许将动态逻辑规则传递到其中的类。前一种方案的开发速度较快,但代价是灵活性较低。后一种选择将具有更高的灵活性,但代价是开发速度较慢。这在每种编码语言中都适用,因为总有 N 个可能的解决方案。

有许多工具可以帮助您提高初始开发速度和灵活性。例如,ORM 工具可以提高数据库访问代码的开发速度,同时还可以灵活地选择 ORM 支持的任何特定数据库实现。从您的角度来看,这是在时间和灵活性方面的净收益减去工具的成本(其中一些是免费的) ,根据开发时间的成本相对于业务需求的价值,这对您来说可能是值得的,也可能不值得。

但是,对于这种编码风格的对话,本质上就是领域驱动设计(Domain Driven Design) ,您必须考虑编写您正在使用的工具所花费的时间。如果您要编写 ORM 工具,甚至编写数据库访问逻辑,使其能够支持该工具提供的所有实现,这将比硬编码您计划使用的具体实现花费更长的时间。

总之,工具可以帮助您抵消自己的生产时间和灵活性的价格,通常是通过将这些时间的成本分配给购买工具的每个人。但是,包括使用工具的代码在内的任何代码都将受到速度/灵活性关系的影响。通过这种方式,领域驱动设计提供了比将业务逻辑、数据库访问、服务访问和 UI 代码整合在一起更大的灵活性,但代价是生产成本。领域驱动设计服务于企业级应用程序比小型应用程序更好,因为企业级应用程序的初始开发时间相对于业务价值而言成本更高,而且因为它们更复杂,它们也更容易受到变更的影响,需要更大的灵活性和更低的时间成本。

在 DDD 中,持久性模型和领域模型是不同的吗?

在 DDD 中有 领域模型储存库。就是这样!如果在存储库中您将直接持久化域模型,或者如果您将在持久化域模型之前将其转换为持久化模型,那么这取决于您自己!这是个设计问题,你的设计。 域不关心如何保存模型。它是存储库的一个实现细节,对于域来说并不重要。这就是存储库的全部目的: 将持久性逻辑和细节封装在其中。

但是作为开发人员,我们知道并不总是可能构建一个100% 不受持久性干扰影响的域,即使它们是不同的东西。译自: 美国《科学》杂志网站(https://stackoverflow. com/a/34436709/890890)原文地址: http://stackoverflow. com/a/34436709/890890我详细描述了一些优点和缺点,即领域模型完全是自由的,并且与持久性模型完全隔离。