首頁  >  文章  >  php框架  >  在laravel使用Repository Pattern(倉庫模式)

在laravel使用Repository Pattern(倉庫模式)

藏色散人
藏色散人轉載
2021-02-01 11:04:012870瀏覽

Laravel##laravel中使用Repository 讓

文章正文Repository 模式主要想法是建立在一個資料操作代理層上的,把controller裡的資料運算分離出來,這樣做的好處有以下幾點:

1 把資料處理邏輯分離讓程式碼更容易維護

2 資料處理邏輯和業務邏輯分離,可以將這兩個程式碼分別進行測試

3 減少程式碼重複

4 降低程式碼出錯的幾率

#5 讓controller程式碼的可讀性大大提高

如圖所示Repository的分層關係

在laravel使用Repository Pattern(倉庫模式)然而,要獨立一個操作層出來,那就會增加大量程式碼,非常繁瑣。如果你是小項目,未必需要使用這個模式。但如果是4-5年以上的複雜大型項目,這種模式的好處就比較明顯了。

學習Repository Pattern的意義不只是為了使用它,更會讓你深入思考框架的分層思想,你開始不僅關注怎麼使用一個框架,還會想了解怎樣設計一個框架,也許會成為你往高階段編程的入口。當你感悟到什麼是一種想法的時候。 。 。


Repository Pattern(倉庫模式)#雖然說設計模式和語言及框架無關,但是脫離了語言及框架,我們很難理解,所以還是在laravel的脈絡下來學習。

public function index(){

    $posts = Post::whereIn('category_id',[1,2])
        ->where('is_draft',0)
        ->orderBy('created_at', 'desc')
        ->take(5)
        ->get();

    return view('front.index',compact('posts'));}

以上是典型的Eloquent資料查詢程式碼,如果你程式設計經驗豐富,你會發現這種程式碼在控制器裡到處都是,而且有很多是重複的,可讀性很差;我們的目標是把它精簡:

仔細觀察

Post::whereIn('category_id',[1,2])->where('is_draft',0)->orderBy('created_at', 'desc')->take(5)->get();

其實它由3部分組成.

第一是

Post

資料模型;第二個是

whereIn('category_id',[1,2])->where('is_draft',0)->orderBy('created_at', 'desc')-> take(5)

,資料操作條件;第三個是

get()

資料取得的方法;我們知道,

Eloquent

裡面有個Query Scope,可以用來把第二部分,也就是查詢條件精簡。所以,在使用了Query Scope後,我們可以把精簡成:<pre class="brush:php;toolbar:false">Post::ofCategory([1,2])-&gt;isDraft()-&gt;orderBy('created_at', 'desc')-&gt;take(5)-&gt;get();</pre>咋一看上去,好像也沒怎麼精簡啊,但實際上你已經實現程式碼解耦和復用了,比如說

isDraft()

, 這個程式碼可以到處用,不用擔心耦合問題。 精簡程度和你的邏輯抽象程度有關,比如說你完全可以寫成:

Post::findPosts([1,2],0,'desc',5)->get();

在輕型專案中,強烈建議使用

Query Scope

,這是一種良好的程式設計習慣。 在更複雜的專案中,

Query Scope

就不夠用了,因為它和資料模型還是一種強耦合,Repository Pattern就是要把第一,第二,第三部分全部解耦;說到解耦,我們在

Laravel

的文檔攻略中講過,第一神器就是PHP中的介面( Interface
下面來看範例
第一步建立資料夾

app
Repositories
Interfaces
Implements

Interfaces裡面用來放接口,Implements用來放介面的實作;

第二步驟 建立一個介面

在上方的

Interfaces

目錄新建一個檔案PostInterface.php: <pre class="brush:php;toolbar:false">namespace App\Repositories\Interfaces;Interface PostInterface{        public function findPosts(Array $cat_id,$is_draft,$order,$take)   {     }}</pre>第三步驟 建立一個介面對應的實作

在上面的

Implements

目錄新建一個檔案PostRepository.php:<pre class="brush:php;toolbar:false">namespace App\Repositories\Implements;use Post;class PostRepository Implements PostInterface{         public function findPosts(Array $cat_id,$is_draft,$order,$take){                 $query = Post::whereIn('category_id',$cat_id)                     -&gt;where('is_draft',$is_draft)                     -&gt;orderBy('created_at', $order)                     -&gt;take($take)                     -&gt;get();                 return $query;         }}</pre>很明顯,倉庫指的就是一個倉庫介面的實作;這裡定義你的業務邏輯;

第四步 在ServiceProvider中綁定介面

開啟

app/Providers/AppServiceProvider

, 在register()加入程式碼:<pre class="brush:php;toolbar:false">&lt;?php namespace App\Providers;use Illuminate\Support\ServiceProvider;class AppServiceProvider extends ServiceProvider{ public function boot(){ } public function register(){ $this-&gt;app-&gt;bind('App\Repositories\Interfaces\PostInterface', 'App\Repositories\Implements\PostRepository');         }}</pre>我們知道,ServiceProvider是Laravel IOC容器實作動態換介面實作的地方,所以我們在這裡綁定一下,這樣我們使用的時候,不直接使用介面實現,而是用ioc容器解析接口,它會幫你自動找到對應好的實作。這意味著,以後需要更換實現,可以在這裡更換;

第五步  使用倉庫

回到我們的controller裡來

use App\Repositories\Interfaces\PostInterface;class PostController extends BaseController{    
    public function __construct(PostInterface $post){ 

        $this->postRepo = $post;    
    }    

    public function index(){ 

        $this->postRepo->findPosts([1,2],0,'desc',5);    
    }}

从上面的例子看,我们的业务逻辑变得非常精简,完全不用管查询;而且也现实了数据查询部分的解耦。

以上是在laravel使用Repository Pattern(倉庫模式)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:learnku.com。如有侵權,請聯絡admin@php.cn刪除