【发布时间】:2015-10-25 14:49:18
【问题描述】:
尝试使用规范模式并遇到了让它在不同的实现中工作的问题(例如,在内存、orm 等中)。我的主要 ORM 是 Doctrine,这意味着我的第一选择是让规范使用 Criterias,因为它们适用于 ArrayCollections(用于 InMemory 实现)和 ORM。不幸的是,它们可以运行的查询种类相当有限(不能执行连接)。
例如,假设我有一个 UserHasBoughtProduct 规范,该规范在构造函数中被赋予了产品 ID。规范编写起来非常简单。
public function isSpecifiedBy(User $user)
{
foreach ($user->getProducts() as $product)
{
if ($product->getId() == $this->productId)
{
return true;
}
}
return false;
}
但是,如果我想找到所有购买过该产品的用户怎么办?我需要通过某种 findSpecifiedBy(Specification $specification); 将此规范传递给我的 UserRepository方法。但这在生产中不起作用,因为它必须检查数据库中的每个用户。
我的下一个想法是规范只是一个接口,实现由基础设施处理。因此,在我的 persistence\doctrine\user\ 目录中,我可能有一个 UserHasBoughtProduct 规范,而在我的 persistence\InMemory\user 目录中我还有另一个。这在某种程度上可行,但在代码中使用非常烦人,因为我需要我的所有规范都可以通过 DI 容器或某种工厂获得。更不用说,如果我有一个需要多个规范的类,我需要通过构造函数将它们全部注入。味道不好。
如果我可以简单地在一个方法中执行以下操作会更好:
$spec = new UserHasBoughtProductSpecification($productId);
$users = $this->userRepository->findSatisfiedBy($spec);
//or
if ($spec->isSatisfiedby($user))
{
//do something
}
有没有人在 PHP 中做过这方面的经验?您是如何设法实现规范模式,使其能够在现实世界中工作并在不同的后端(如 InMemory、ORM、纯 SQL 或其他任何东西)中使用?
【问题讨论】:
标签: php doctrine-orm domain-driven-design specifications