質問: 現在laravel5.5を利用してwebアプリケーションを製作しております。 db操作が多くなってきたことからrepositoryパターンの実装を検討しているのですが、実装する上でrepositoryに実装すべき処理の範囲が不明瞭になってしまったので、そちらに関してご教授頂きたく思います。 「コントローラ、サービス、リポジトリ、モデル」の4つがある場合に関してです。 まず私の現在のそれぞれに対する認識は以下のようなものです ###### コントローラー: 詳細なロジックは一切記述せず、サービスのメソッドを呼び出す役割と、ビューにレスポンスを返す役割を担う。 ###### サービス: ビジネスロジックを記述しdb操作を行う場合はリポジトリのメソッドを呼び出す役割を担う。 ###### リポジトリ: モデルを利用したDB操作を記述する。 ###### モデル: dbに対するsql発行をテーブルごとに分かりやすくしてくれる物であり、 独自にメソッドを追加すべきではない。 このような認識を持っていたのですが、先日他の方のコードを拝見させて頂いた際に、モデルに独自メソッドをいくつか記入しdb操作を全てモデルが担うように実装している方がいました(リポジトリは利用していない) 私はこの実装に納得してしまいました。 これならリポジトリパターンで行おうとしているビジネスロジックとdbアクセスの分離が問題なく出来ていますし、余計にリポジトリクラスを増やす手間も省けるではないですか。 だったら「なぜこの便利なモデルクラスというものが存在するlaravelでリポジトリパターンを実装したがる人がいるのか」と思ったわけです。 ど素人の考えですのでとんだ的外れな質問になってしまっているかもしれないのですが、以上を踏まえてリポジトリパターンのメリット、また実装時のモデルとリポジトリの使い分けに関してご回答いただけると幸いです。
回答: PHPはよく知らず、今さっきググっただけの知識なので間違いがあるかもしれませんが、ご使用のフレームワークで言うところのmodelは、DBのとあるテーブルの構造ままを表したマッピング用のオブジェクトという認識でよいですか? とりあえずORマッパーのように、フレームワークの文脈に従ってコードを書けば、簡単にオブジェクトを検索登録更新削除できるようなもの、という前提で話をします リポジトリパターンは結局のところ、永続化層とのやり取りを抽象化してメリットを得ることを目的としたパターンと捉えてよいです(この手の何たらパターンというのは、大抵何らかの対象を抽象化する代物であることが多いです) それによって、DB固有の問題やテーブル設計、ORマッパーなどのライブラリの仕様、そして、それらの変更に振り回されずに開発を進められることを期待しています インピーダンスミスマッチという用語が示すように、オブジェクト指向プログラミングとリレーショナルデータベース間のミスマッチで複雑さがあちこちに紛れ込んでしまうことは多々あります データベースの操作の難しさは本来アプリケーションで解決したい問題と直接関わりがないので、それに振り回されるのは望ましくないです また、特定のDB(Oracleなど)や特定のORマッパーなどに直接依存すると、ロックインしてそうそう変更できなくなります(バージョンアップも大変です) これらの問題は、リポジトリを上手く使えば軽減できます 実装面に着目すると例えば、多くの開発者がテーブルの設計が変わってコードを何箇所も修正するような経験があるかと思いますが、リポジトリに操作を集約しておけばリポジトリを使う側の修正はほぼ不要になるので、そのような時でも対応が楽になるでしょう(テストや調査もしやすくなりますね) ORマッパーなどの外部ライブラリに依存したコードもリポジトリの実装に隠蔽されるので、バージョンアップやライブラリ自体の変更に対応しやすくなります また、一つのトランザクションで複数のテーブルを正確に更新しなければならない、バグが発生しやすく使う側も注意が求められる複雑な操作も、リポジトリに集約すればだいぶ扱いやすくなります 以上のようなメリットを享受するためにリポジトリパターンは利用されます 実装についてもう少し具体的に言うと、リポジトリインターフェースを作成し、業務ロジックはそれに依存する(呼び出す)。そのインターフェースには、DIコンテナなどを用いて具象リポジトリをインジェクションする。ミドルウェアの変更などあった場合は、それ用の具象クラスを新たに作成しインジェクションする、感じになるでしょう これらはつまり抽象化によるメリットですので、対象のシステムで管理対象のクラスが増えることと比べて十分なメリットが得られないのであればリポジトリパターンは不要です 小規模なアプリに対しては些か過剰でもあります ですが、作っているアプリが将来的にどうなるかでも変わってくるので要不要の判断は非常に難しいです なので、少しでも変更が容易くなるよう自動テストとかCIとかアジャイルとか諸々の手法の出番となるわけですが、本題とズレるのでおしまいにします 結局のところixaさんの開発しているシステムの属性で変わってきますので、上述したようなメリットとデメリットを踏まえた上でどうするのかを判断するしかありません この記事など参考になるかと思います