贫血领域模型与简单领域驱动设计中的领域模型对比

17
我最近读到了一篇关于 "贫血领域模型模式" 的帖子,引起了我的注意。阅读过程中,我发现贫血领域模型的描述适用于我参与和构建的许多项目。我从未认为这是一个糟糕的设计决策,因为它感觉非常自然。我认为,在领域模型轻量且不太复杂的情况下,贫血领域模型名称非常合适。为什么要增加领域模型的复杂性,如果不需要,只是为了使"贫血领域模型"这个标题不能恰当地描述您的代码呢?
问题:在什么时候,将更多的代码复杂性塞入您的服务/应用程序层,变得不正确,而是将复杂性暴露在实体对象之外?我完全赞成在实体上拥有一个"总计"属性,其中它可以在内部计算出"总计"的值。我不赞成使实体直接与各种其他小部件通信,以确定其属性的结果。那么,贫血领域模型的概念是一种反模式还是很好的关注点分离?贫血领域模型的标题总是不好的吗?
只是好奇其他人对这个设计(反)模式的看法。
3个回答

9
如果领域是轻量级的(也就是不复杂),建议在核心领域层中使用简单的ActiveRecord类型对象。通常情况下,数据库表格和您的领域对象之间存在一对一的映射关系,并且这里并没有很多“逻辑”。你的应用程序只是在数据库和用户界面之间移动记录,允许简单的CRUD操作。
对于复杂的领域,您需要构建一个核心领域模型,其中一些对象最终会映射到数据库表格,而有些则代表领域中除了纯数据之外的其他概念。如果应用程序需要协调多个领域对象,适当时将其放在对象内部或服务对象中。
无血统领域模型反模式适用于当您拥有复杂的领域时,但您将所有(或几乎所有)逻辑都放在核心领域对象之外时。
关键区别在于您放置逻辑的位置。如果您没有太多逻辑,显然领域对象看起来只是简单的数据容器。如果您有复杂的逻辑,请不要将其全部从领域对象中提取出来,而是适当地在核心领域对象和领域服务之间进行分离。

这是我读过的最好的简单解释,向新手开发人员讲述了ADM所有炒作的真正含义。谢谢你,先生。 - Riegardt Steyn

9
关键问题是要问为什么领域模型是贫血的?
  • 是否因为商业逻辑几乎不存在,例如主要是由CRUD屏幕组成的应用程序?
  • 服务导向架构中,“领域对象”实际上是数据传输对象这样的简单结构?
  • 政治或实用考虑因素(如代码所有权或前/后向兼容性)过度阻碍重构?
  • 在其他面向对象语言中应用过程化/关系型设计?

无论如何,如果我要选择一个简单的经验法则来界定领域模型逻辑和服务逻辑之间的边界,那就是在领域内与相关对象进行交互是可以的,而访问“外部世界”(用户界面、Web服务等)可能不属于领域模型。


如果我所有的业务规则都在服务类中,但它们不是Web服务(而且我根本不使用Web服务),我能否将我的Arch SOA称为呼叫? - Omu
@Omu 我猜你可以这样做,但我更倾向于称其为普通的过程/关系代码。SOA是以过程化风格编写代码的动机,而不是对其的描述。 - Jeffrey Hantin

1

你好!

如果你把逻辑放在领域对象之外,你就完全失去了面向对象编程的一个主要概念:封装(或数据隐藏)。

AOP 在一定程度上弥补了这个问题,但毕竟,面向对象编程的一个关键概念已经消失了。

祝好, Stefan


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接