DB操作に関連するスマートな実装パターンであるリポジトリパターンについてかいてみようかと思います。
データの操作に関連するロジックをビジネスロジックから切り離し、抽象化したレイヤに任せることで保守や拡張性を高めるパターンです。
(必ずしもDB操作のロジックのみを留めるパターンというわけではないそうです。)
Laravelにリポジトリパターンを取り入れることで、
といったメリットを得ることができます。
Modelと同じ単位でRepositoryディレクトリを作成します。(賛否両論あるかもです)
今回は以下のような構成でリポジトリパターンを実装していきます。
.
├── Models
│ ├── User.php
│
├── Repositories
└── User
├── UserRepository.php
└── UserRepositoryInterface.php
まずはインターフェースを設計します。
<?php
namespace App\Repositories\User;
interface UserRepositoryInterface
{
/**
* Nameで1レコードを取得
*
* @var string $name
* @return object
*/
public function getFirstRecordByName($name);
}
続いて実装クラスを用意します。
ここでは対応するモデルのDIとメソッドの実装を行います。
<?php
namespace App\Repositories\User;
use App\Models\User;
class UserRepository implements UserRepositoryInterface
{
protected $user;
/**
* @param object $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
/**
* 名前で1レコードを取得
*
* @var $name
* @return object
*/
public function getFirstRecordByName($name)
{
return $this->user->where('name', '=', $name)->first();
}
}
ここから更にService層を用意してクラスを追加し、抽象度を高める場合もあるようですが、今回はこの2つのクラスのみで実装していくことにします。
AppServiceProvider.phpにインターフェースと実装クラスを登録します。
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
// User
$this->app->bind(
\App\Repositories\User\UserRepositoryInterface::class,
\App\Repositories\User\UserRepository::class
);
}
}
実装したリポジトリパターンを使用します。
<?php
namespace App\Http\Controller\User;
use App\Repositories\User\UserRepositoryInterface;
class UserController extends Controller
{
public function __construct(UserRepositoryInterface $user_repository)
{
$this->user_repository = $user_repository;
}
public function index()
{
return $this->user_repository->getFirstRecordByName($name);
}
}
インターフェースをインジェクションするだけです!
モデルもコントローラーもすっきりしました。
これを機にDDDの勉強もしたいです。
関連書籍