存储库模式是过程性的,而不是 OOP?

The repository pattern is procedural, not OOP?

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

索赔 1:

The repository is not an object. It is a procedural boundary and an explicit contract that requires as much effort when naming methods upon it as the objects in your domain model do.

声明 2:

The repository is the contract between the domain model and the persistence store. It should be only written in terms of the domain and without a thought to the underlying persistence framework. Define intent and make it explicit; do not treat the repository contract like object oriented code.

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

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

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

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

The repository is not an object.

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

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

话虽这么说,但您在使用它时 "see" 并不了解它的大部分面向对象特性。存储库是出现 "flat" 的类似服务的对象,即它不公开可导航的对象结构,仅公开方法。这是作者在句子中陈述的

do not treat the repository contract like object oriented code

另一种说法,

Define intent and make it explicit

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

除此之外,我认为您对过程代码的恐惧可能是没有道理的。 C# 是一种混合范式语言,小型编程通常是过程式、命令式编程。使用更新的语言功能,使用函数式编程(我是它的忠实粉丝)来解决相同的问题也变得越来越简单,例如使用 LINQ,但这并不会使程序样式变坏。大型编程仍然以面向对象的方式进行。

The repository is not an object. It is a procedural boundary

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

如果你 GetAll() 然后 Add() 一些东西到 Repo 然后再 GetAll() ,你不会期望得到相同的结果。您正在与之交谈的对象已更改

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

隐藏了它的内部状态,a.k.a。封装它,因为您只能访问接口,而不是底层持久性细节。

您可以将消息 传递到存储库(调用其方法),并且可能会"discussion" 具有相同的存储库。

对象形式非常适合存储库的工作类型。

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