尝试使用规范模式并遇到在不同实现(例如内存,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 中做过这个?你是如何实现规范模式的,使其在现实世界中可用于不同的后端,比如内存、ORM、纯 SQL 或其他任何东西?