16

我最近阅读了一篇关于“贫血域模型模式”的文章,引起了我的注意。当我阅读本文时,我发现贫血域模型描述适用于我从事和构建的许多项目。我从不认为这是一个糟糕的设计决定,因为它感觉很自然。我认为在域模型重量轻且不是很复杂的情况下,贫血域模型这个名字非常适合。为什么要在不需要的领域模型中增加复杂性,以至于“贫血领域模型”的标题不能恰当地描述您的代码?

问题:在什么时候将更多的代码复杂性填充到您的服务/应用程序层中变得不正确而有利于暴露实体对象的复杂性?我完全赞成在实体上拥有一个“总计”属性,它可以在内部计算出总计的值。我不是为了让实体直接与其他各种小部件通信以确定它的属性之一的结果。那么贫血域模型的概念是反模式还是良好的关注点分离?标题贫血域模型总是一件坏事吗?

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

4

3 回答 3

9

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

对于复杂的域,您将构建一个核心域模型,其中一些对象最终映射到 DB 表,而有些可能不映射,并且代表您域中的其他概念,而不仅仅是纯数据。如果需要在多个域对象之间进行协调,应用程序的逻辑应该在适当的时候在对象内或在服务对象内。

贫血域模型反模式适用于当您有一个复杂的域但不是适当地将一些逻辑放在域对象中并将一些逻辑放在服务中时,您将所有(或几乎所有)逻辑放在核心域对象之外。

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

于 2009-07-21T00:23:15.073 回答
9

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

  • 几乎完全没有业务逻辑,例如在主要是CRUD 屏幕组合的应用程序中?
  • 面向服务的架构中的“领域对象”实际上是简单的结构 数据传输对象
  • 过度阻碍重构的政治或务实考虑,例如代码所有权或前向/后向兼容性?
  • 以其他面向对象的语言应用程序/关系设计?

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

于 2009-09-08T22:13:57.363 回答
1

天!

如果您将逻辑放在域对象之外,您将完全失去主要的 OO 概念之一:封装(或数据隐藏)。

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

问候,斯特凡

于 2009-09-08T21:42:25.867 回答