【问题标题】:The repository pattern is procedural, not OOP? [closed]存储库模式是程序性的,而不是 OOP? [关闭]
【发布时间】:2015-11-23 15:54:40
【问题描述】:

嗯,我一直在读一本关于领域驱动设计的书,它的标题是领域驱动设计的模式、原则和实践(PPPDDD)。到目前为止,我一直很喜欢阅读它,它为 .NET 世界中的 DDD 提供了很多见解。然而,有一件事情让我很困扰。在第 21 章(Repository 模式)中,作者提出了这两个主张:

权利要求 1:

存储库不是对象。它是一个程序边界和显式契约,在为它命名方法时需要付出与领域模型中的对象一样多的努力。

权利要求 2:

存储库是域模型和持久存储之间的契约。它应该只根据领域编写,而不考虑底层持久性框架。定义意图并使其明确;不要将存储库合同视为面向对象的代码。

所以存储库模式不是面向对象的,而是程序化的?您同意本书作者的说法吗?为什么明确存储库方法,例如 findByUsername(string Username) 使存储库本质上是程序化的?

我想编写 OO 代码,而不是程序代码。如果存储库是程序性的,那么它完全扼杀了我使用这种模式的目的。我真希望作者说的不是真的,你怎么看?

顺便说一句,我提供了本书作者声称存储库在下面的程序部分的快照,如果有帮助,请查看它们:

【问题讨论】:

  • 作者的意思很简单,你不应该在设计存储库合约时考虑到 OCP,允许传递任意查询对象。
  • 是的,尽管作者提出了一些奇怪的主张,但他们的主要观点似乎是“在实践 DDD 时不要实现不灵活的 IRepository 模式,而是使用对领域的数据需求建模的显式查询方法"。

标签: .net oop repository domain-driven-design repository-pattern


【解决方案1】:

存储库不是对象。这是一个程序边界

我完全不同意这一点。存储库是事物的集合。

如果你 GetAll() 然后 Add() 到回购,然后 GetAll() 再次,你不会期望得到相同的结果。你说话的对象变了

=>它有一个内部状态,或者至少它在外界看来是这样的。

隐藏其内部状态,也就是封装它,因为您可以访问的只是接口而不是底层持久性细节。

您可以将消息传递到存储库(调用其方法)并与同一存储库进行可能很长的“讨论”。

对象形式非常适合存储库所做的工作。

书中程序这个词的使用充其量是尴尬的,最坏的情况是误导。它具有显式契约这一事实与编程风格无关。

【讨论】:

  • 我同意你的观点,当我从书中进一步阅读时,似乎作者误用了程序这个词。虽然它非常令人困惑,是的 Repository 是并且应该是一个对象。
【解决方案2】:

我认为作者想强调某一点,但这样做会造成混乱。例如

存储库不是对象。

如果不是一个对象,那又是什么呢?这本书似乎是在 .NET 的上下文中,所以作者当然不是说我们应该创建静态存储库函数。那太荒谬了。

我可以向你保证,存储库是一个普通的 .NET 对象。

话虽如此,您在使用它时并没有“看到”很多它的面向对象特性。存储库是一个类似服务的对象,看起来“扁平”,即它不公开可导航的对象结构,只是方法。这是作者在句子中说明的

不要将存储库合同视为面向对象的代码

另一种说法,

定义意图并使其明确

在我的经验中经常被忽略。通常会创建能够处理所有类型的域对象的通用存储库实现。虽然这乍一看似乎是个好主意,但它不符合 DDD 的精神。您应该使用在您的域上下文中有意义的显式查找器方法创建存储库。

除此之外,我认为您对程序代码的恐惧可能是不合理的。 C# 是一种混合范式语言,小型编程通常是过程式、命令式编程。随着新的语言特性,用函数式编程(我非常喜欢)解决同样的问题也变得越来越简单,例如使用 LINQ,但这并不会使程序样式变差。大型编程仍然以面向对象的方式进行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 2017-04-25
    • 2015-08-13
    • 1970-01-01
    • 2015-07-05
    • 1970-01-01
    • 2010-10-12
    相关资源
    最近更新 更多