Laravel Repository 倉庫模式

1. Repository 模式作用和實現原理;

  • 理論
MVC 分層缺點
MVC 作爲一種傳統的分層模型已經服務過很多 WEB 應用,非常成熟。Controller 需要直接調用對應的 Model 來完成數據交互,這樣不可避免的造成了強耦合,也造成了 Controller 和 Model 的臃腫
一般控制器每個方法的代碼不會超過 20 行,而且最好不直接引用 Model 的實例。而 Model 的功能應該是非常單一的,應該是單純定義與數據庫有關的業務關係,而不是大量書寫邏輯業務代碼,保持它們的純粹對於項目來說是非常重要的。
Repository 模式
如果以 MVC 的模式實現,就是 Controller 與 Model 之間的直接交互,這樣強耦合是不可避免的。
以公司的部門來舉例,可以不讓 Controller 部門直接與 Model 部門打交道,而是成立一個新的中間部門來統一調配,這個部門就是 Repository。也就是說,Controller 和 Model 不用糾結代碼應該寫在哪裏,它們都不用做這個事情,讓 Repository 來專職做這件事情。M 和 C 只要做好各自的基本業務就行了。Controller 就負責請求的邏輯調用,Model 只負責數據庫的交互。
Repository 擅長根據請求來決定如何調用數據,而且只做這件事情。
在這裏插入圖片描述
Laravel 框架中 Repository 模式的實現原理
接口綁定
依賴注入
  • 代碼實例
  • 新建 app/Repositories/StudentRepository.php
<?php

namespace App\Repositories;

interface StudentRepository{

    public function findAll();

    public function delete($sid);

}
  • 新建 app/Repositories/StudentRepositoryEntity.php,實現一個實體類
<?php

namespace App\Repositories;
use App\Student;

class StudentRepositoryEntity implements StudentRepository{

    public function findAll(){
        return Student::all();
    }

    public function delete($sid){
        $student = Student::find($sid);
        return $student->delete();
    }
}
  • 修改 app/Providers/AppServiceProvider.php
    • 可以自定義一個服務提供者(provider),也可以在已有的服務提供者(provider)裏, 將實體類和 interface 類綁定即可
    • 注意:如果是自定義的provider,需要將 provider 類放到 config/app.php 配置文件中的 providers 選項中。
<?php

// use App\Repositories\StudentRepository;
// use App\Repositories\StudentRepositoryEntity;

/**
* Register any application services.
 *
 * @return void
 */
public function register()
{
    //$this->app->bind(StudentRepository::class, StudentRepositoryEntity::class);
    $this->app->bind('App\Repositories\StudentRepository', 'App\Repositories\StudentRepositoryEntity');
}
  • 修改 routes/web.php,新建路由,依賴注入
Route::any('repository', function (\App\Repositories\StudentRepository $studentRepository){
    dd($studentRepository->findAll()); 
});

2. Laravel Repository 擴展包的配置和使用;

# 進入項目目錄
cd /data/project/test/laravel1

# 安裝 l5-repository
composer require prettus/l5-repository

# 安裝 fractal
composer require league/fractal

# 安裝完成後配置
  • 修改 config/app.php
/*
 * Package Service Providers...
 */
// Repository
\Prettus\Repository\Providers\RepositoryServiceProvider::class,
  • 控制檯生成配置文件
php artisan vendor:publish
  • 修改新生成的配置文件 config/repository.php
// 約定了一些目錄結構
// models 的目錄改成 Models(個人喜好)
/*
|--------------------------------------------------------------------------
 | Generator Config
 |--------------------------------------------------------------------------
 |
 */
 'generator'  => [
     'basePath'      => app()->path(),
     'rootNamespace' => 'App\\',
     'stubsOverridePath' => app()->path(),
     'paths'         => [
         'models'       => 'Models',
         'repositories' => 'Repositories',
         'interfaces'   => 'Repositories',
         'transformers' => 'Transformers',
         'presenters'   => 'Presenters',
         'validators'   => 'Validators',
         'controllers'  => 'Http/Controllers',
         'provider'     => 'RepositoryServiceProvider',
         'criteria'     => 'Criteria'
     ]
 ]
  • 控制檯操作
php artisan make:entity User

# 會出現一系列的提問,全部設置 y
Would you like to create a Presenter? [y|N] (yes/no) [no]:
 > y

App\Transformers\UserTransformerPresenter created successfully.

 Would you like to create a Transformer? [y|N] (yes/no) [no]:
 > y

Transformer created successfully.

 Would you like to create a Validator? [y|N] (yes/no) [no]:
 > y

Validator created successfully.

 Would you like to create a Controller? [y|N] (yes/no) [no]:
 > y

Request created successfully.
Request created successfully.
Controller created successfully.
Repository created successfully.
Provider created successfully.
Bindings created successfully.

# 新生成了如下圖的目錄和文件
# 在 app/Http/Controllers/ 生成了一個 UsersController.php
# 裏面的代碼是一個典型的 RESTful 風格
# 已經把基本的代碼結構都生成好了

# 在 app/Http/Providers/ 生成了一個 RepositoryServiceProvider.php
# boot() 方法自動綁定了接口的實例

# 在 config/app.php 中,在 Application Service Providers... 添加一下內容
App\Providers\RepositoryServiceProvider::class,

# 總結:Laravel5 的 Repository 框架可以自動生成一個 RepositoryServiceProvider
# 然後自動去綁定一些接口和實體類
# 這樣就可以很方便的去搭建一個 Repository 模式
  • 新生成的目錄和文件
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章