从php存储库

时间:2018-03-27 03:45:14

标签: php

我的问题:我被要求从存储库中的书籍列表中获取特定数据,并为用户提供仅显示英语书籍的选项。所以,我试图通过使用get的函数运行它并且它没有工作。是否有一种简单的方法从存储库中提取特定数据?

1 个答案:

答案 0 :(得分:0)

您可以使用以下界面:

  • Repository - 加载,插入,更新和删除实体
  • Selector - 在存储库中找到基于过滤器的实体
  • Filter - 封装过滤逻辑

我的Repository与数据库无关;实际上它并没有指定任何持久性;它可以是任何东西:SQL数据库,xml文件,远程服务,来自外太空的外星人等。     对于搜索功能,Repository会构建一个Selector,可以对其进行过滤,LIMIT - 编辑,排序和计算。最后,选择器从持久性中提取一个或多个Entities

以下是一些示例代码:

<?php

interface Repository
{
    public function addEntity(Entity $entity);

    public function updateEntity(Entity $entity);

    public function removeEntity(Entity $entity);

    /**
     * @return Entity
     */
    public function loadEntity($entityId);

    public function factoryEntitySelector():Selector
}


interface Selector extends \Countable
{
    public function count();

    /**
     * @return Entity[]
     */
    public function fetchEntities();

    /**
     * @return Entity
     */
    public function fetchEntity();
    public function limit(...$limit);
    public function filter(Filter $filter);
    public function orderBy($column, $ascending = true);
    public function removeFilter($filterName);
}

interface Filter
{
    public function getFilterName();
}

然后,一个实现:

class SqlEntityRepository
{
    //...
    public function factoryEntitySelector()
    {
        return new SqlSelector($this);
    }
    //...
}

class SqlSelector implements Selector
{
    //...
    private function adaptFilter(Filter $filter):SqlQueryFilter
    {
         return (new SqlSelectorFilterAdapter())->adaptFilter($filter);
    }
    //...
}

class SqlSelectorFilterAdapter
{
    public function adaptFilter(Filter $filter):SqlQueryFilter
    {
        $concreteClass = (new StringRebaser(
            'Filter\\', 'SqlQueryFilter\\'))
            ->rebase(get_class($filter));

        return new $concreteClass($filter);
    }
}

标志是通用Selector使用Filter但实施SqlSelector使用SqlFilter; SqlSelectorFilterAdapter使通用Filter适应具体的SqlFilter

客户端代码创建Filter个对象(通用过滤器),但在选择器的具体实现中,这些过滤器在SQL过滤器中进行转换。

其他选择器实施,例如InMemorySelector,使用其特定FilterInMemoryFilter转换为InMemorySelectorFilterAdapter;所以,每个选择器实现都有自己的过滤器适配器。

使用此策略,我的客户端代码(在bussines层中)并不关心特定的存储库或选择器实现。

/** @var Repository $repository*/
$selector = $repository->factoryEntitySelector();
$selector->filter(new AttributeEquals('activated', 1))->limit(2)->orderBy('username');
$activatedUserCount = $selector->count(); // evaluates to 100, ignores the limit()
$activatedUsers = $selector->fetchEntities();