带有ORM的DDD业务逻辑应该去哪里?


10

我过去使用过MDA(模型驱动的体系结构)工具,我们通过UML进行建模,这会生成业务实体(我们的域模型)和ORM(映射等)。

该域上的许多业务代码和服务都是该模型的一部分,并且我们的存储库正在返回业务实体(因此,不可能切换到另一个ORM(不是我们想要的))。

但是,现在我正在开始一个项目,我想从DDD角度进行思考。

到目前为止,感觉好像我将业务逻辑放入域模型中,并通过存储库与ORM(无论选择哪种)一起使用。但是,如果我想继续在应用程序的ORM部分中使用MDA工具,则此处创建的模型将非常贫乏(即不包含任何业务逻辑)。同样,如果我将实体框架(.net)或NHibernate用于我的ORM,它也将是贫血模型。我不确定如果我刚刚使用NHibernate,您会将业务逻辑放在哪里。

我是否以这种方式正确思考,换句话说,使用DDD使用域中的所有业务逻辑,而仅使用ORM通过存储库进行持久化?

Answers:


12

因此不可能切换到另一个ORM(不是我们想要的)。

好像错了 存储库模式的主要优点是隐藏了数据访问逻辑,并且可以轻松交换。

到目前为止,感觉好像我将业务逻辑放入域模型中,并通过存储库与ORM(无论选择哪种)一起使用。但是,如果我想继续在应用程序的ORM部分中使用MDA工具,则此处创建的模型将非常贫乏(即不包含任何业务逻辑)。同样,如果我将实体框架(.net)或NHibernate用于我的ORM,它也将是贫血模型。我不确定如果我刚刚使用NHibernate,您会将业务逻辑放在哪里。

贫血领域模型被许多人(例如Martin Fowler)认为是不良做法。您应该避免这样的设计,因为这样的模型会导致过程设计技巧,而不是好的面向对象设计。然后,您将拥有数据类和管理器/处理类,这意味着您将状态和行为分开了。但是,一个对象确实应该是“状态行为”。

NHibernate在持久性无知方面做得很好。您可以使用XML或FluentNHibernate隐藏映射详细信息,而只需编写普通的POCO。使用NHibernate创建富域模型非常容易。我认为您也可以使用实体框架和MDA工具来做到这一点。只要此工具生成部分类,您就可以相当轻松地扩展生成的代码,而不必担心新一代可能会破坏用户编写的代码。

简而言之。当您使用NHibernate时,什么也没做,我什么也没重复,使您无法使用丰富的域模型。我建议将它与FluentNHibernate一起使用,并手动进行映射。映射代码只需要5到10分钟即可编写。我想对于实体框架也是如此,它的工具至少会创建易于扩展的部分类。

我是否以这种方式正确思考,换句话说,使用DDD使用域中的所有业务逻辑,而仅使用ORM通过存储库进行持久化?

在大多数情况下,您是正确的。您应该有一个丰富的域模型。尤其是当事情变得越来越复杂时,如果正确设计,它更易于维护和扩展。但是请记住,DDD还知道(域层和应用程序层)服务以实现业务逻辑,工厂也知道工厂以封装创建逻辑。

我也倾向于将业务逻辑分为领域逻辑和实际应用程序业务逻辑。域逻辑是域交互和行为的方式,而完全不同的应用逻辑封装了域如何用于特定用例/应用程序。通常,我不得不更新域模型以支持特定的用例并使其更强大。


2
+1:我还将域逻辑层与应用程序逻辑层分开。我将所有ORM和数据库内容放入域逻辑层。应用程序逻辑层对ORM,事务和所有其他内容一无所知:它仅查看业务逻辑类并调用其方法。我发现这种方法对于拥有更简单,更干净的应用程序逻辑层非常有效。
乔治

@Falcon:感谢您提供信息。当我提到贫血模型时,我的意思是,如果我使用DDD创建域,则我的存储库的一个版本可能是mda版本,在该版本中,我只是将实体移至mda实体(即贫血模型),然后将其持久化在交易等方面。可以吗?我怀疑我会使用MDA工具,但只是想了解如果需要的话。听起来对吗?
JD01

@ JD01:我不太了解您,但是听起来您想转换域模型实体,以便可以轻松地持久化它们。这就像使用DTO和automapper(google it)可能是完成此任务的有用工具。这种方法不一定会干扰DDD最佳实践。毕竟,存储库还意在隐藏数据访问逻辑。您只需将幕后的Business对象转换为MDA DTO,然后将其持久保存,API用户甚至不会注意到。我认为可以。
猎鹰

1
@ JD01:我建议您看一下以下链接,看看有多少企业Java专家这样做。他们基本上有一个DAO,一个DTO和BO(业务对象)。对我来说,层太多了,但设计还可以。java.sun.com/blueprints/corej2eepatterns/Patterns/…–
Falcon

@Falcon:是的,我一直在考虑将DTO作为我的MDA对象,而不是那样做。只需掌握DDD播放器d0的各个部分。再次感谢。
JD01

3

但是,如果我想继续将MDA工具用于应用程序的ORM部分,则此处创建的模型将非常贫乏(即不包含任何业务逻辑)。

我不知道您使用的是哪种MDA工具,但是我使用的工具始终会创建部分类,因此您可以随意使用所需的任意业务逻辑来完成它们。

但是,我确实认为MDA工具在DDD上下文中比ORM不太合适,因为代码生成通常倾向于生成类,这些类混有特定于工具的噪声,而不是我们期望的精简,明确表达的域实体。实际上,您经常得到的是域数据,持久性逻辑,约束验证逻辑的混合...而且我不知道是否有一种方法可以将大多数MDA工具分离这些问题。

当然,除了通过部分类,您无法触摸生成的代码,这意味着您无法消除可能集成的潜在的反DDD行为。在您要在聚合之间强制设置严格的屏障并完美地调整实体之间的关系的方法中,这是有问题的。在连续集成环境中的构建时间也可能会遭受额外的代码生成步骤。

除此之外,我认为Falcon几乎说了全部-在ORM或MDA工具中,绝对没有任何东西可以阻止您拥有丰富的域实体。


嗨,我使用的是来自enabledobjects.com的ECO(企业核心对象),它与您所描述的完全相同。
JD01

1

我在团队中所做的工作是对对象,域进行建模并同时添加我的业务逻辑。我不使用“模型驱动开发”来从模型中生成代码,但更喜欢使用注释方法。我的意思是,在类图中的对象级别,我添加了ORM构造型。这将直接在与EJB3 / hibernate兼容的代码中添加持久性注释。数据库创建是由Hibernate完成的,当然不是由UML模板完成的。这样会好很多,因为如果代码更改并且添加的注释与休眠专家不完全相同,则他/她可以更改它,但是模型仍然不错。我也可以更改自己的要求,但是我的域模型仍然可以。

开发人员可以在每种方法中添加业务逻辑并添加注释,我也可以建模并添加约束。例如,如果销售额不超过5万,等等。...我不需要编写代码,只需在模型中编写即可,并且开发人员团队可以看到此信息。真正的酷炫和灵活的UML。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.