logaretm/depo

简单灵活的存储库模式实现。

0.2.4 2016-01-10 09:26 UTC

This package is not auto-updated.

Last update: 2024-09-24 20:16:07 UTC


README

laravel 框架的简单灵活存储库模式实现。

动机

我被Jeffery Way的laracasts视频关于装饰模式和存储库模式实现所启发,虽然我完全清楚这些模式有时可能有些过度,但我一直在尝试寻找两者的最佳结合;简单性和功能性。

保持简单 :)

基本存储库实现的问题在于,有时你需要所有查询构建器的功能,我的意思是向你的契约、存储库类和缓存存储库中添加一个getCompletedTasks,这不是特别直接。通常你只想添加一个作用域方法或直接使用where子句。这正是此实现所考虑的。

以下是一些相关视频链接

装饰存储库

简化存储库

安装

此包可以通过composer轻松安装,只需运行

composer require logaretm/depo

摘要

此包提供了存储库类的使用基础类和契约,以及这两个基础类的一般实现。

RepositoryBaseRepository类仅作为Eloquent模型的一个包装器。这可以是一个放置复杂查询的好地方。

CachingRepositoryBase类是RepositoryBase对象的一个装饰器,它使用缓存标签缓存查询结果,因此请确保您的缓存驱动程序支持缓存标签功能(redis/memcache)。

CachingRepositoryBase还允许在数据库中创建/更新/删除模型记录。在执行这些操作后,它会清除相关的缓存结果,然后在下一次查询执行时缓存新结果,确保您的查询与数据库保持最新。

用法

有几种使用类的方法。但首先以下代码片段假设存在一个Task模型。

class Task extends Model
{
    /**
     * @var array
     */
    protected $fillable = [
        'body',
        'completed'
    ];


    /**
     * @param $query
     * @return mixed
     */
    public function scopeCompleted ($query)
    {
        return $query->where('completed', true);
    }


    /**
     * @param $query
     * @return mixed
     */
    public function scopeInProgress ($query)
    {
        return $query->where('completed', false);
    }
}

这是一个基本模型,具有两个作用域。

现在要使用这些类,你有多种方式,使用适合你需求的方式。

使用通用实现

使用Repository类,你可以轻松地通过依赖注入为Task模型创建一个存储库。

$repository = new Repository(new Task);

然后,如果我们需要一个用于Task模型的缓存存储库,我们只需将之前创建的存储库对象注入到构造函数中即可。它接受一个存储库(或模型)和一个记忆时长(以分钟为单位),以及支持标签的缓存存储。

$cachingRepository = new CachingRepository($repository, 10, app()['cache.store']);

您也可以在不创建底层存储库的情况下实例化缓存存储库,它内部会为您创建一个。

$cachingRepository = new CachingRepository(new Task, 10, app()['cache.store']);

现在您可以进行一些查询,请注意,这两个类都提供了一个流畅的API,您可以在最后一个调用的方法不返回Builder对象的情况下链式调用方法。

$completedTasks = $cachingRepository->where('completed', true)->get();

或使用我们之前创建的作用域。

$completedTasks = $cachingRepository->completed()->get();

虽然这两个类简单直观,但它们并没有解决存储库模式可以解决的一些问题。例如,如果您有一些复杂的查询,那么将其与模型混合在一起可能并不理想,您需要一些负责此任务的东西。

这就是第二种方式介入的地方,扩展基础类。

扩展基础类

扩展存储库基础类,并提供一个实现getRepositoryModel方法的实现,该方法应返回在此存储库中使用的模型类型。

class TaskRepository extends Repository
{
   /**
    * Yep. that is it.
    *
    * @return mixed
    */
   function getRepositoryModel()
   {
       return Task::class;
   }
}

虽然 RepositoryBase 类的构造函数允许进行模型注入,但您可以跳过注入,Laravel 的 IOC 容器将创建该模型。

$taskRepository = new TaskRepository;

或者

$taskRepository = new TaskRepository(new Task);

现在,要为模型创建缓存仓库,您还需要扩展 CachingRepositoryBase 基类。

class CachingTaskRepository extends CachingRepositoryBase
{
    /**
     * Returns the primary cache key for this repository.
     *
     * @return mixed
     */
    public function getCacheTag()
    {
        return 'tasks';
    }

    /**
     * Returns the cache tags to be forgotten.
     *
     * @return mixed
     */
    public function getForgetTags()
    {
        return ['tasks'];
    }
}

使用 RepositoryBase 类的实例来实例化它,并提供缓存时长和缓存存储。

$cachingRepository = new CachingTaskRepository($taskRepository, 10, app()['cache.store']);

现在,您已经准备好缓存您的查询了,任何未包含在仓库对象中的方法都将委派到底层的查询构建器,这样您就可以使用您的范围方法,以及查询构建器提供的任何功能。

$completedTasks = $cachingRepository->completed()->get();

许可证

该软件包采用 MIT 许可证授权。