PHP存储库模式实现问题

时间:2014-06-05 21:30:00

标签: domain-driven-design repository-pattern ddd-repositories

存储库应该从服务调用中返回什么?

实体(或实体集合),或者是对自身的引用,然后可以用于访问包含实体集合的属性,例如?

获取此示例代码:

$user = $userRepository->findById(1);

$users = $userRepository->findAll();

我认为在大多数代码中,用户实体对象或用户集合实体都会从这样的调用中返回。

我觉得有点奇怪,从一个方向来说,一个Repository会直接返回对象,但是从另一个方面来看,它会在对它们起作用之前将它们保持在状态。以此示例代码为例:

$user = $factory->make('user');
$user->setName($array_data['name']);

$repo->add($user);
$repo->save();

这就是它的完成方式吗?

我认为我希望在检索方面看到更多这样的东西:

$users = $userRepository->findAll(); // Returns $userRepository reference

foreach($users->collection() as $user) {
    // Do some operations, or whatever
}

$users->save();

或者,对于只读需求:

$users = $userRepository->findAll();
$users = $users->collection(); // Returns User Entities held in state

澄清为什么以这种或那种方式完成它将非常感激。

工厂属于域名?

它应该作为Mapper对象的依赖项注入吗?似乎还必须从控制代码/服务层获得Factory访问权限,以创建要提交到存储库的实体。

这导致我的下一个问题......

从控制类/服务层创建新实体的首选方法是什么?

我见过使用Factory对象,如下所示:

$user = $factory->make('user');
$user->setName($array_data['name']);

$repo->add($user);

以及内置的Repository方法,如下所示:

$repo->saveFromArray($array_data);

在第二个示例中,$ array_data将通过存储库转发到Mapper,然后Mapper将执行保存。当然,在任何一个例子中,都会预先检查数据源的重叠记录。

我认为第一种方法更受青睐?这似乎是一种更加面向对象的方法。

1 个答案:

答案 0 :(得分:1)

你有很多问题......

  

存储库应该从服务调用中返回什么?

始终聚合根(AR)。 AR设计非常重要,但它并不是存储库的关注点。存储库方法根据域的需要返回一个或多个对象。没有用户集合Enitity,有一个用户列表(在php中可能是一个数组),不会使事情变得复杂。

对于域需要(读取或写入),域存储库应仅 。返回整个对象,存储库不返回AR的片段,而是返回整个AR。我再次提到AR设计非常重要。

  

工厂属于域名?

需要的地方。我不使用工厂,最多我有工厂方法,但即使是为了恢复目的(如果我使用纪念品)。您不必使用工厂来创建域对象。

  

从控制类/服务层创建新实体的首选方法是什么?

最简单的方法。对于大概99%的案例,您将使用" new"运营商。仅使用工厂 ,如果它为特定实体提供了具体的好处。

Mapper从不执行保存,因为它是一个映射器。只有存储库才能执行持久性工作。 Mappers将数据从一个模型转换为另一个模型。您可以使用映射器将域对象映射到某些数据模型,以便持久化并返回。

相关问题