Laravelでリポジトリーパターンを実装して見た感想
どうも、いっき(@kzkohashi)です。
Laravel
を使い始めて1年くらいたちそうなので、いくつか試している実装パターンの感想でも書こうと思う。
今回は、Repository
パターンについて書く。
---追記---
リポジトリーパターンを採用しつつバリューオブジェクトについても書いた。
また、Laravel MeetupでDDDについても発表したまとめ。
Repositoryパターンとは?
Repository
パターンとはビジネスロジックとデータ操作のロジックを分離し、データ操作のロジックを抽象化するパターンと認識してる。
例えばユーザーが新規登録したとして、今までだと
View -> UserController -> UserSerive(ビジネスロジック/データ操作)
View
から受け取ったフォームデータをコントローラーで受け、サービス層で登録処理などをやっていたと思う。
それをRepository
パターンにおきかえると
View -> UserController -> UserSerive(ビジネスロジック) -> UserRepository(データ操作)
このようになり、データ操作のロジックとビジネスロジックを分離する。
Repository
パターンのほうの実装を簡単に書くと(Controllerは省略)
<?php interface UserRepository { public function create($name, $email, $password_hash); } class EloquentUserRepository implements UserRepository { private $user; public function __construct(User $user) { $this->user = $user } public fucntion create($name, $email, $password_hash) { $data = []; $data['name'] = $name; $data['email'] = $email; $data['password] = $password_hash; return $this->user->create(data); } }
<?php class UserService { private $user_repo; public function __construct(UserRepository $user_repo) { $this->user_repo = $user_repo; } public function regist($name, $email, $password) { $password_hash = bcrypt($password); $user = $user_repo->create($name, $email, $password_hash) $user->notify(); return $user; } }
注目すべきところはサービスからUserRepository
が呼ばれているが、実装はEloquentUserRepository
で行なっていること。
理由としてはインターフェースを通して実行することで、ORM
による依存を排除し、サービス側は実装の内容を意識しなくて良い。
Laravelでの実装
簡単にテストまでの奴を書いた。
簡単に構成を説明すると、
- インターフェース:
App\Repositories
- 実装:
App\Infrastracture\Repositories
- サービスコンテナの登録:
App\Providers\RepositoryProvider
らへんを見てもらえるとリポジトリーパターンの実装の仕方がわかると思う。
リポジトリの作成は結構手間だけど、aiiroが実装してくれたコマンドを使えば容易に作れる。
php artisan app:make:repository ItemRepository
良かったところ
悪かったところ(反省点?)
- Eloquentがサービス層に漏れている
- 結局返す値がEloquentじゃデータ操作ができてしまう
- 完璧なリポジトリーパターンを目指すには、Entityでのやりとりなどが必要
今後の改善点
リポジトリーパターンはDDD
を行うための実装方法の一つで、実際すべてを行うのはなかなかしんどい。
なので次はEloquent
の一部の値をValueObject
に置き換え、DDD
に近づけていく。