数据映射器和存储库之间到底有什么区别?

问题描述 投票:17回答:2

好吧,我一直在尝试找出数据映射器和存储库之间的区别,但是到目前为止,我仍然没有。在我看来,专家程序员说:“存储库是在集中查询构造代码的映射层上的另一抽象层”。看起来可以理解,但仍然有些抽象。我之前读过这篇有关stackoverflow的文章,这让我更加困惑:How is the Data Mapper pattern different from the Repository Pattern?

我想我需要的是简单的解释和关于这两种模式如何不同以及存储库做什么而数据映射器没有做什么,反之亦然的具体/实践示例。你们中没有人知道一个很好的例子来说明数据映射器和存储库的概念吗?如果是相同的示例,则更好,一个示例使用数据映射器,另一个示例使用存储库。谢谢,我非常感谢。到目前为止,我还是很困惑...

orm repository repository-pattern datamapper domain-model
2个回答
23
投票

假设您的应用程序管理Person对象,每个实例都具有nameagejobTitle属性。

您想保留此类对象,从持久性介质中检索它们,并可能进行更新(例如,在其生日时增加年龄)或删除。这些任务通常在创建,读取,更新和删除中称为CRUD。

最好将“业务”逻辑与处理Person对象的持久性的逻辑分离。这使您可以更改持久性逻辑(例如,从数据库更改为分布式文件系统),而不会影响业务逻辑。

您可以通过将所有持久性逻辑封装在Repository后面来完成此操作。假设的PersonRepository(或Repository<Person>)将允许您编写如下代码:

Person johnDoe = personRepository.get(p=> p.name == "John Doe"); johnDoe.jobTitle = "IT Specialist"; personRepository.update(johnDoe);

这只是业务逻辑,并不关心对象的存储方式和位置。

Repository的另一侧,您同时使用了DataMapper和用于将查询从功能描述转换为内容的内容(p=> p.name == "John Doe"到持久层可以理解的内容)。

您的持久层可以是一个DB,在这种情况下,DataMapper会将Person对象与PersonsTable中的一行进行转换。然后,查询翻译器将功能查询转换为SELECT * FROM PersonsTable WHERE name == "John Doe"

另一个持久层可以是文件系统,也可以是另一种选择将Person对象存储在两个表PersonAgePersonJobTitle中的DB格式。

[在后一种情况下,DataMapper的任务是将johnDoe对象转换为两行:一列用于PersonAge表,另一列用于PersonJobTitle表。然后,查询逻辑需要将功能查询转换为两个表上的join。最后,DataMapper需要知道如何根据查询结果构造Person对象。

在大型,复杂的系统中,您希望使用小型组件来完成细小,明确定义的事情,并且可以独立开发和测试:

  • 业务逻辑在想要读取或保留对象时会处理Repository,而不关心它是如何[。
  • Repository要在特定持久性介质中读取/写入对象时处理DataMapper
  • [用于查询,Repository依赖于DataMapper提供的架构(例如,在jobTitle表的JobTitle列中找到PersonTable值),但不依赖于任何
  • 实现
  • 一个映射器。对于数据库持久性,DataMapper依赖于
  • DB层
  • ,将其与Oracle / Sybase / MSSQL / OtherProvider详细信息屏蔽。
这些模式没有“不同”,它们只是暴露了不同的基本特征。

17
投票
我意识到这个答案有点晚了,但是它可能会在将来帮助某个偶然发现相同问题的人,并发现可用的答案不能完全回答这个问题(我第一次遇到这个问题时就感到这个问题)。

[阅读PoEAA(Martin Fowler)之后,我也难以识别数据映射器和存储库之间的差异。

这是我发现这两个概念最终归结为:

    一个
  • 存储库就像域对象的集合,具有强大的查询功能(Evans,DDD)
  • a
  • DataMapper
  • “在对象和数据库之间移动数据,同时使它们彼此之间以及映射器本身保持独立”(Fowler,PoEAA)

Repositories

是一个通用概念,不必一定要存储到数据库中,它的主要功能是提供对域对象的访问(如启用查询的访问)(无论它们是从数据库获取的)除了重点)。存储库可能(并且经常会)包含DataMappers本身。

DataMappers

充当域对象和数据库之间的中间层,从而使它们可以独立发展,而彼此之间互不依赖。数据映射器可能具有“查找”或查询功能,但这并不是它们的主要功能。您发现您在DataMappers中使用复杂的查询逻辑的次数越多,您就越想开始考虑将查询逻辑解耦到存储库中,同时又让DataMappers充当其主要功能,将域对象映射到数据库,反之亦然。
© www.soinside.com 2019 - 2024. All rights reserved.