我正在尝试学习域驱动设计(DDD),我认为我有了基本的想法。但是有些让我困惑的事。
在DDD中,持久性模型和域模型是不同的东西?我的意思是,我们设计的域名和类只考虑了域名问题;没关系。但在那之后,当我们构建我们的存储库或任何其他数据持久性系统时,我们是否应该创建另一个模型以在持久层中使用?
我在想我们的域模型也用于持久化,这意味着我们的存储库从查询中返回我们的域对象。但今天,我读了这篇文章,我有点困惑:
Just Stop It! The Domain Model Is Not The Persistence Model
如果这是真的,那么从域对象中获得单独的持久性对象会有什么好处呢?
答案 0 :(得分:57)
只要想到这一点,域模型就应该依赖于任何东西,并且其中没有基础设施代码。域模型不应该是可序列化的,也不应该从某些ORM对象继承,甚至不能共享它们。这些都是基础设施问题,应该与域模型分开定义。
但是,如果您正在寻找纯DDD,那么您的项目就会在初始开发速度上重视可扩展性和性能。很多时候,将基础架构问题与“域模型”混合在一起可以帮助您以可扩展性为代价在速度上取得很大进步。关键是,你需要问自己,“纯DDD的好处是否值得开发速度的成本?”。如果你的答案是肯定的,那么这就是你问题的答案。
让我们从一个示例开始,其中您的应用程序以域模型开始,而恰好是数据库中的表与您的域模型完全匹配。现在,您的应用程序突飞猛进,并在查询数据库时开始遇到性能问题。您已经应用了一些经过深思熟虑的索引,但是您的表增长如此之快,以至于您可能需要对数据库进行反规范化以便跟上。因此,在dba的帮助下,您提出了一种新的数据库设计来处理您的性能需求,但现在这些表与以前的方式大不相同,现在您的域实体的块大部分都分布在多个表中而不是它是每个实体的一个表。
这只是一个示例,但它说明了为什么您的域模型应该与持久性模型分开。在此示例中,您不希望突破域模型的类以匹配您对持久性模型设计所做的更改,并且实质上更改域模型的含义。相反,您希望更改新的持久性模型和域模型之间的映射。
保持这些设计分离有几个好处,例如可扩展性,性能和响应数据库更改的反应时间,但您应该权衡它们与初始开发的成本和速度。通常,从这种级别的分离中获得最大收益的项目是大规模企业应用程序。
评论员更新
在软件开发领域,有第N种可能的解决方案。因此,在灵活性和初始开发速度之间存在间接的反比关系。作为一个简单的例子,我可以将逻辑硬编码到类中,或者我可以编写一个允许将动态逻辑规则传递给它的类。前一种选择将具有更高的开发速度,但代价是灵活性较低。后一种选择具有更高的灵活性,但代价是开发速度较低。这在每种编码语言中都适用,因为总有第N种可能的解决方案。
有许多工具可以帮助您提高初始开发速度和灵活性。例如,ORM工具可以提高数据库访问代码的开发速度,同时还可以灵活地选择ORM支持的任何特定数据库实现。从您的角度来看,这是时间和灵活性的净增益减去工具的成本(其中一些是免费的),根据相对于价值的开发时间的成本,这可能是也可能不值得。业务需求。
但是,对于编码样式中的这种对话,实质上就是Domain Driven Design,你必须考虑编写你正在使用的工具所花费的时间。如果您要编写ORM工具,甚至以支持工具为您提供的所有实现的方式编写数据库访问逻辑,那么只需要对您计划的特定实现进行硬编码就需要更长的时间。在使用。
总之,工具可以帮助您抵消自己的生产时间和灵活性价格,通常是将购买该工具的每个人的成本分摊。但是,包括使用工具的代码在内的任何代码都将受到速度/灵活性关系的影响。通过这种方式,域驱动设计允许比将业务逻辑,数据库访问,服务访问和UI代码整合在一起时具有更大的灵活性,但代价是生产时间。领域驱动设计比小型应用程序更好地服务于企业级应用程序,因为企业级应用程序在初始开发时间方面往往与业务价值相关的成本更高,并且因为它们更复杂,所以它们也更容易受到需要更大灵活性的变化。及时降低成本。
答案 1 :(得分:13)
在DDD中,持久性模型和域模型是不同的东西吗?
是的,但这并不一定意味着一组不同的类来明确表示持久性模型。
如果使用关系数据库进行持久化,那么诸如NHibernate之类的ORM可以通过映射到域类来处理持久性模型。在这种情况下,没有显式的持久性模型类。这种方法的成功取决于ORM的映射功能。例如,NHibernate可以通过component mappings支持中间映射类。这允许在需要时使用显式持久性模型类。
如果使用文档数据库进行持久化,则通常更不需要持久性模型,因为域模型只需要可序列化以便持久化。
因此,当存在通过ORM映射到域模型无法实现的复杂映射时,请使用显式持久性模型类。无论实现如何,域模型和持久性模型之间的差异仍然存在。
答案 2 :(得分:12)
在DDD中,持久性模型和域模型是不同的东西吗?
在DDD中,您拥有域模型和存储库。而已。如果在存储库内部,您将直接保留域模型或将其转换为持久性模型,然后再保留它取决于您!这是设计和设计的问题。
正如其他aswers指出的那样,每个选项都有其优点和缺点。请看一下 answer ,其中详细介绍了其中一些内容。