数据映射器模式和集合责任


Data Mapper pattern & Collection responsibility

我有一个关于集合的数据映射器模式的问题。我一直在关注这篇关于存储库、集合和数据映射器模式的文章,我发现它们非常有用,但我需要澄清一些事情:

在这些示例中,UserMapper 在其构造函数中采用 UserCollection,这意味着 UserMapper 实际上负责获取从查询中返回的数据,并从该数据构建集合。

这不是有点违反SRP吗?DataMapper 不应该只从查询中返回一个原始数组,而不是同时构建并返回该数据的集合包装器吗?以代码为例,以下哪一个更合适?

$userCollection = new UserCollection;
$userMapper = new UserMapper;
$userCollection->addUsers( $userMapper->fetchAll() ); // where addUsers() takes an array and does what it needs to

$userMapper = new UserMapper( new UserCollection );
$userCollection = $userMapper->fetchAll() // where fetchAll() queries the DB, then builds and returns a collection

第一个有点麻烦,但它不是更松散耦合吗?

集合出于各种原因都很有用,我将概述示例/用途;

1) 如果您有 10000000 个用户并希望找到所有用户怎么办?

如果您生成一个包含所有项目的数组,您将很快耗尽内存,为这么多对象加载完整的对象图。

如果你有一个集合,你可以遍历整个集合,一次加载一个集合。这要好得多。尽管有时您可能想要所有项目的数组,但这不是常态。

2) 补水对象

您可以拥有一个集合,该集合将在创建对象时对其进行水化处理。例如;

如果您有 User 对象,但一个用户可以有多个地址、电子邮件地址等。创建主 User 对象时,集合对象可以是水化/填充依赖对象的完整图形的过程的一部分。

3) 代理集合/延迟加载

您可能有一个艺术家对象,它可以有 10000000 个相册。如果加载几个 User 对象,则为每个用户填充相册也会效率低下,但您可以使用集合作为代理,按需延迟加载它们。

集合还有许多其他用途,但仅凭这些用途就足以在正确情况下使用。

数组很好,有其用途,集合也是如此。您可以在适合的时候同时使用它们,这是您在设计应用程序时需要做出的决定。