持久性应该是域对象的责任吗? (你能评论一下这篇文章吗?)

时间:2009-09-29 15:29:13

标签: domain-driven-design

我读了article

在源代码中,Entity对象正在执行所有CRUD操作。这意味着Entity对象直接从方法调用Repository。

评论表明:

  

持久性绝对是域对象的责任

这是对的吗?

5 个答案:

答案 0 :(得分:1)

“持久性是一个基础设施方面,域层应该从中解耦”:我引用你提到的文章。

持久性由Repository实现处理。域对象应该不知道属于这样的存储库。

回答你的问题,我可以说没有正确或错误的做法,但声明是有争议的。如果您的项目以一致的方式执行此操作并且您对该方法没有问题,那么这可能是最佳实践。在我看来,域对象应该不知道持久性问题,因此从纯粹的DDD视图中该语句是错误的。

答案 1 :(得分:1)

在我看来,作者倾向于采用Active Record模式。我不确定DDD是否严格禁止使用Active Record,但我不会使用它。

有关Active Record和DDD问题的详细介绍,请参阅this article

答案 2 :(得分:1)

他的观点是实体对象应该不仅仅是数据载体。

不是将一些实体逻辑放在DAO层中,而是将更多逻辑放入业务层,他认为实体的所有逻辑都应该在该实体中。

这肯定有一些优点。例如:

public class Parent {
    @Lazy
    private List<Children> children;
}

在您的代码中,您从数据库中获取父级。不久之后,你决定和孩子们做点什么。在DAO世界中,DAO框架必须以某种方式在某处注入一个隐藏字段,允许getChildren()从数据库中获取父项的子项。

如果该字段是Parent的一部分,那么它的工作原理将非常明显。

业务逻辑也是如此:如果您在实体中更改某些内容,则必须查找将其用作业务逻辑的所有位置,并确保更改不会破坏任何内容。如果所有业务逻辑都在实体中,这将更加简单。

不幸的是,OO语言不会发生这种情况。主要问题是你在每个实体中都有太多的代码,而对于某些代码,它根本不清楚它将属于哪个实体。想象一下一些业务逻辑,它从输入实体读取数据并将其写入输出实体。这些代码属于哪个实体?输入还是输出?

OO根本不允许将这些问题切成可消化的碎片。

答案 3 :(得分:1)

如果你阅读了这些评论,你会看到作者解释说这篇文章主要是为了展示DI技术,而不是为了促进良好的DDD设计。评论中讨论的源代码有几个很好的问题。所以在使用它作为参考之前你最好三思而后行。

要回答您的问题,通常不建议让实体使用存储库接口,尤其是持久性实现。我会将此与“goto”用法联系起来 - 这可能需要 ,但您通常不会期望在代码中看到它。

我还可以补充一点,如果不将它们绑定到存储库,则使用域对象要容易得多。例如,您可以轻松地构建FitNesse(验收)测试,而不会弄乱数据库或处理实体对存储库的调用。单独使用域对象越简单越好。

答案 4 :(得分:1)

在不阅读文章的情况下,我可以说我永远不会将我的数据访问层写为域对象的一部分。

域对象是应用程序中最敏感的部分之一,因为它们正在所有应用程序层中使用。如果你想在某天更改持久层,那么将持久性逻辑放在其中会给你带来很多麻烦。

此外,使用这些对象的大多数代码应该对它们甚至持久存在的事实无动于衷。