域驱动设计,映射器/存储库值高于/低于

时间:2013-04-21 09:16:52

标签: php domain-driven-design repository-pattern

在我正在开发的项目中,我们使用域驱动设计。有了这个,我们还使用映射器和存储库模式。映射器只是crud操作,而存储库看起来就像实体。

所以它看起来像

class UserMapper
{
    public function fetch($criteria)
    {
         // magic on the database
    }
}

class UserRepository
{
    public function getByName($name)
    {
        $this->mapper->fetch(array('name' =>  $name));
    }
}

代码不起作用,但它提供了一般性的想法

现在我遇到了以下问题

假设我希望用户名为“john”,性别为“男性”。如果存储库现在具有函数getByNameAndGender($ name,$ gender)。但是你会很快获得很多功能,因为你需要性别,年龄和名字等等。

接下来,我发现的所有示例只实现了以下“value == value”。但是没有找到像“值< value”之类的东西或其他东西的单一例子。所以我的问题是你如何实现这一点。因为我再次看到你可以创建像

这样的函数
getWhereHeightIsLowerThan($height)
getWhereHeightIsLowerThanOrEquals($height)
getWhereHeightIs($height)
getWhereHeightIsGreaterThan($height)
getWhereHeightIsGreaterThanOrEquals($height)

对于应该像1个函数的东西,再次有5个函数。如何在存储库/映射器模式中实现它。为了使事情更加复杂,我没有使用SQL数据库。但MongoDB,现在应该不是一个大问题。

-

使用eulerfx给出的答案我附带以下代码

使用Application \ Specification \ AbstractSpecification;

class IdIsSpecification extends AbstractSpecification
{
    /** @var  string */
    protected $id;

    /**
     * @param $id
     * @throws \InvalidArgumentException
     */
    function __construct($id)
    {
        if(!is_string($id))
        {
            throw new \InvalidArgumentException('Expects string, given ' . gettype($id));
        }

        $this->id = $id;
    }

    /**
     * @return mixed
     */
    public function getQuery()
    {
        return [
            '_id' => new \MongoId($this->id),
        ];
    }
}

我使用php,所以我不能使用AND和OR这样的词,所以将它们重命名为ALSO和OF。

规范模式也会查看投射到它的数据集。这是我的需求而不是最好的方法,所以我使用方法getQuery而不是isSatisfied。

所有查询逻辑都在规范中找到。存储库使用规范comon函数构建,例如get by id。

映射器只是数据的简单crud处理程序(fetch,fetchAll,count,insert等)。

最后,如果我想更改数据库语言(从mongo语法到sql),我只需要更改getQuery方法。希望它有所帮助

1 个答案:

答案 0 :(得分:2)

您似乎正试图解决复杂查询的复杂性。为此,您可以使用specification pattern。使用规范模式,您将拥有一个表示查询的对象。该对象由关于手头实体的谓词组成,例如WhereHeightIsLowerThan 3。然后,存储库将基于此规范对象构建SQL查询或MongoDB查询。