推薦:好用的 Laravel Repository 包

什麼是Repository模式,如何使用Repository模式

這裏就再也不囉嗦了,請參見如下幾個連接
如何使用 Repository 模式?
關於 Repository 的設計模式
laravel-china.org搜索laravel

個人使用歷程

起因

MVC在現在仍然是流行趨勢,但多數框架都只提供基礎的MVC架構。
幾年前在開發中咱們常常會遇到問題Model過於臃腫,寫着寫着就會變成相似於萬能類,最後面的人就真成了接盤俠了。
很不幸我就是其中之一。後來我就一直在思考如何才能讓Model看起來清爽,功能更加單一簡潔。(當時並不知道Repository),終於開始重構。一把心酸淚。。。。。最多的是組合和Traitgit

使用Laravel

最開始接觸Laravel就是感受它的文檔清爽,覺得是個簡單的框架,結果不當心一入坑,才發現被它的外表給欺騙了。
但卻也爲此深深愛上了它,是啊,這不就是我一直追求的嗎?無限的靈活性,可替換,越研究代碼愈加現到處都是精髓。
但在Laravel中也不可避免的基礎MVC模式,上述問題仍然存在。github

初期使用

一直覺得我都遵循一個核心:以倉庫層爲處理數據基礎,爲SerivceController等提供數據供給,倉庫須要的原始數據則經過Model中獲取。這樣能夠徹底分離ModelController的依賴。
最開始在Laravel中使用是經過定義大量的RepositoryInterface來注入,bind,實現具體的Repository工做類。
這是理想的使用方法可替換性很強。設計模式

遇到的問題

  • 實際開發過程當中Repository基本不會被替換,無數的Interface帶來的規範,也帶來了開發的麻煩。
  • 在使用Repository模式中咱們不斷的注入Model,每一個方法都須要直接Model來進行一次次的查詢數據集,卻失去了在外層鏈式調用的便捷性(這其實並不合理,但存在即有起因)。

中間的折中

後來索性在開發中咱們去掉了Interface的約束,直接做用功能類來注入使用,此時簡潔性和便捷性大大的提升,若是非要替換仍然bind能夠解決問題。這樣的開始一直持續很長時間。可是像連接調用仍然沒有解決,爲些咱們開發出了新的倉庫包。https://github.com/crcms/repository架構

再次輪迴

開始玩微服務,開始分離代碼,固然就離不開RPC,十分慶幸咱們使用了Repository模式,經過開啓對應的Rpc Repository,咱們能夠很快進行本地Repository切換,以Interface來約束。app

便捷的Repository包

基礎示例

class TestRepository extends AbstractRepository
{
    /**
     * @var array
     */
    protected $guard = [
        'id', 'title','other'
    ];

    /**
     * @return TestModel
     */
    public function newModel(): TestModel
    {
        return app(TestModel::class);
    }

    /**
     * @param int $perPage
     * @return LengthAwarePaginator
     */
    public function paginate(AbstractMagic $magic = null, int $perPage = 15): LengthAwarePaginator
    {
        $query = $this->where('built_in', 1);

        if ($magic) {
            $query->magic($magic);
        }

        return $query->orderBy($this->getModel()->getKeyName(), 'desc')->paginate($perPage);
    }

    /**
     * @param int $name
     * @param int $title
     */
    public function updateName(string $name, string $title)
    {
        $this->getModel()->where('name', $name)->update(['title' => $title]);
    }
    
}

超好用的Magic方法

在多條件搜索中,確定會存在大量的判斷,優雅度過低,如:框架

if($request->input('username')) {
    $query->where('username',$username)
}

if($request->input('email')) {
    $query->where('email',$email)
}

.......

但經過QueryMagic方法咱們能夠輕鬆優雅解決這些問題,示例:微服務

建立Magicui

use CrCms\Repository\AbstractMagic;
use CrCms\Repository\Contracts\QueryRelate;

class TestMagic extends AbstractMagic
{
    /**
     * @param QueryRelate $queryRelate
     * @param int $id
     * @return QueryRelate
     */
    protected function byName(QueryRelate $queryRelate, string $name)
    {
        return $queryRelate->where('name', $name);
    }

    /**
     * @param QueryRelate $queryRelate
     * @param string $title
     * @return QueryRelate
     */
    protected function byTitle(QueryRelate $queryRelate, string $title)
    {
        return $queryRelate->where('title', 'like', "%{$title}%");
    }

    /**
     * @param QueryRelate $queryRelate
     * @param int $id
     * @return QueryRelate
     */
    protected function byId(QueryRelate $queryRelate, int $id)
    {
        return $queryRelate->where('id', $id);
    }
}

使用Magic(這裏只是簡單示例):this

public function paginate(array $condition, int $perPage = 15): LengthAwarePaginator
    {
        return $query->magic(new TestMagic($condition))->orderBy($this->getModel()->getKeyName(), 'desc')->paginate($perPage);
    }

更多

開發此包的緣由是在這以前我並示找到我想要的(適合個人)兼具Model的靈活性以及數據倉庫的分離模式,因此爲此開發了這個倉庫包。目前此包已經使用在好幾個項目中目前運行良好。
後面還打算兼容TP以及Yii等使用率高的框架,暫時只支持Laravel
更多詳情,請移步github:https://github.com/crcms/repository

最後

哈哈,請原諒我着急的文本描述,但願對須要的人以及面臨和我曾經同樣困惑的人有所幫助。
原文出處:crcms-blog

相關文章
相關標籤/搜索