在简单的域驱动设计中的贫血域模型与域模型

And*_*mer 16 design-patterns anti-patterns

我最近读了一篇关于" 贫血领域模型模式 "的文章引起了我的注意.当我读完这篇文章时,我发现Anemic Domain Model描述适用于我已经开发和构建的许多项目.我从未认为这是一个糟糕的设计决定,因为它感觉非常自然.我认为,在领域模型重量轻且不是非常复杂的情况下,贫血领域模型的名字非常适合.为什么要增加域模型的复杂性,而不必仅仅因此"Anemic Domain Model"的标题不能恰当地描述您的代码?

问题:在您的服务/应用程序层中填充更多代码复杂性的时间点变得不正确,有利于暴露实体对象的复杂性?我在一个实体上拥有一个"Total"属性,它在内部可以计算出Total的值.我不是让实体直接与各种其他小工具通信,以确定其中一个属性的结果.因此,贫血领域模型的概念是一种反模式还是一种良好的关注点分离?标题贫血领域模型总是一件坏事吗?

只是好奇其他人对这种设计(反)模式的看法.

Jef*_*tin 9

关键问题是问为什么域模型贫血?

  • 几乎完全没有业务逻辑,就像在一个主要是CRUD屏幕组合的应用程序中一样?
  • 面向服务的体系结构,其中"域对象"实际上是简单的结构 数据传输对象
  • 代码所有权或向前/向后兼容性等政治或实用因素会过度阻碍重构?
  • 在面向对象的语言中应用过程/关系设计?

在任何情况下,如果我要为域模型逻辑和服务逻辑之间的边界选择一个简单的经验法则,那么在访问"外部世界"(用户界面, Web服务等)可能不属于域模型.


Dav*_*her 7

如果域是轻量级的(读取:不复杂),建议的方法是在核心域层中使用简单的ActiveRecord类型对象.通常是数据库表和域对象之间的一对一映射,这里没有很多"逻辑".您的应用程序只是在数据库和UI之间移动记录并允许简单的CRUD操作.

对于复杂域,您将构建一个核心域模型,其中一些对象最终映射到数据库表,有些可能不会并且代表域中的其他概念,除了纯数据.如果需要多个域对象之间的协调,应用程序的逻辑应该在适当时在对象内部或在Service对象内.

Anemic Domain Model反模式适用于您拥有复杂域但不是在域对象和服务中的某些逻辑中适当地放置一些逻辑时,您将所有(或几乎所有)逻辑放在核心域对象外部.

这里的关键区别在于您放置逻辑的位置.如果你没有太多,显然域对象看起来只不过是简单的数据容器.如果你确实有复杂的逻辑,不要只是从域对象中提取它,而是在核心域对象和域服务之间适当地分开它.