DDD - 持久性模型和领域模型

ayk*_*ayk 51 oop domain-driven-design model repository repository-pattern

我正在尝试学习域驱动设计(DDD),我认为我有了基本的想法.但是有些让我困惑的事情.

在DDD中,持久性模型和域模型是不同的东西?我的意思是,我们设计的域名和类只考虑了域名问题; 没关系.但在那之后,当我们构建我们的存储库或任何其他数据持久性系统时,我们是否应该创建另一个模型以在持久层中使用?

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

刚刚停止!域模型不是持久性模型

如果这是真的,那么从域对象中获得单独的持久性对象会有什么好处?

Aar*_*ins 64

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

但是,如果您正在寻找纯DDD,那么您的项目就会在初始开发速度上重视可扩展性和性能.很多时候,将基础架构问题与"域模型"混合在一起可以帮助您以可扩展性为代价在速度上取得很大进步.关键是,你需要问自己,"纯DDD的好处是否值得开发速度的成本?".如果你的答案是肯定的,那么这就是你问题的答案.

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

这只是一个示例,但它说明了为什么您的域模型应该与持久性模型分开.在此示例中,您不希望突破域模型的类以匹配您对持久性模型设计所做的更改,并且实质上更改域模型的含义.相反,您希望更改新的持久性模型和域模型之间的映射.

保持这些设计分离有几个好处,例如可扩展性,性能和响应数据库更改的反应时间,但是您应该将它们与初始开发的成本和速度进行权衡.通常,从这种级别的分离中获益最多的项目是大规模企业应用程序.

评论员的最新消息

在软件开发领域,有第N种可能的解决方案.因此,在灵活性和初始开发速度之间存在间接的反比关系.作为一个简单的例子,我可以将逻辑硬编码到类中,或者我可以编写一个允许将动态逻辑规则传递给它的类.前一种选择将具有更高的开发速度,但代价是灵活性较低.后一种选择具有更高的灵活性,但代价是开发速度较低.这在每种编码语言中都适用,因为总有第​​N种可能的解决方案.

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

但是,对于编码样式中的这种对话,本质上是域驱动设计的对话,您必须考虑编写您正在使用的工具所花费的时间.如果您要编写ORM工具,甚至以支持工具为您提供的所有实现的方式编写数据库访问逻辑,那么只需要对您计划的特定实现进行硬编码就需要更长的时间.在使用.

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

  • 这是一个很好的答案,但您一直在重申我们需要“选择”-我希望您能阐明为什么它认为您认为我们也不能吃蛋糕吗?在我看来,如果存在更好的工具来促进此类开发,那么初始开发的速度应该不是一个因素吗?工具还不存在吗? (2认同)
  • 这是一个很好的答案。我想投入我自己的两分钱 - 大多数时候都希望将域模型与持久层分离,尤其是在企业中,但不幸的是,(我认为)许多企业在成长过程中从未过渡到分离域因为很多领域和业务逻辑渗透到了持久层。我主要指的是直接处理数据库并绕过包含大部分域逻辑的应用程序的所有可用额外工具。一个重要的例子是报告。 (2认同)

eul*_*rfx 15

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

是的,但这并不一定意味着一组不同的类来明确表示持久性模型.

如果使用关系数据库进行持久化,那么诸如NHibernate之类的ORM可以通过映射到域类来处理持久性模型.在这种情况下,没有显式的持久性模型类.这种方法的成功取决于ORM的映射功能.例如,NHibernate可以通过组件映射来支持中间映射类.这允许在需要时使用显式持久性模型类.

如果使用文档数据库进行持久化,则通常更不需要持久性模型,因为域模型只需要可序列化以便持久化.

因此,当存在通过ORM映射到域模型无法实现的复杂映射时,请使用显式持久性模型类.无论实现如何,域模型和持久性模型之间的差异仍然存在.

  • 我认为必须在这里添加一些内容.域模型应始终关注域行为,而持久性模型最多存储域对象STATE.持久性模型是您要从对象存储的内容,并且该数据将用于还原对象.您可以使用ORM实体作为域实体的基础,但是您必须将对象强制化以遵守ORM需求.基本上,除了真正的目的之外,您的域对象也必须关注ORM需求.然后你在一个滑坡上. (4认同)

fab*_*tto 12

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

在DDD中,您拥有域模型存储库.而已.如果在存储库内部,您将直接保留域模型或将其转换为持久性模型,然后再保留它取决于您!这是设计和设计的问题.

正如其他aswers指出的那样,每个选项都有其优点和缺点.看一下这个答案,我详细介绍了其中一些.

  • 我阅读了很多关于 DDD 的文章,但你的简短描述是最好的。谢谢你。 (2认同)