お題目
- Eloquentはとっても便利!
- あまりにも便利なのでEloquentをそのままドメインモデルにしたくなっちゃう!
- でも、何も考えずにドメインモデル化すると酷い目に合うかも…?
なんで? 何がいけないの?
Eloquentが扱う問題領域(DB操作)は本来インフラストラクチャ層が正解。
つまり、Eloquentをドメインモデルとして扱ってしまうと、レイヤー構造(≒責務の範囲)の侵犯による副作用が発生する。
つまり…どういうことだってばよ?
1.他層のDB操作に歯止めが掛からなくなる
ドメインクラスを経由すればどこでもDBを弄れるので、最悪だと「アプリケーション層からInsertを書く」なんて芸当が可能。
「ヘボグラマーが各種バリデーションやエラー処理を迂回してDBにダイレクトアタックできてしまう」と言い換えると危険性が伝わりやすいかも?
ユビキタス言語なんて知ったこっちゃねえSQLは高級言語だ世界共通だ、という文化圏の人間でもなければオススメできない世界である。(SIだと稀に見かけるから笑えない)
2.多重責務にEloquentが肥え太る
DBと直接折衝するクラスは取り扱うデータ種が多くなりがち。
データの種類≒扱う責任の種類なので、意識しなければコード量があっという間に肥大していく。
「Order」なんてヘビーなテーブルを扱うEloquentにドメインロジックを生やしてしまえば…後はわかるな?
DDDで推奨される「低粒度なドメインクラスへの分割&マッピング」は、このような問題を強制解決する効能もある。
まとめ
- インフラストラクチャ層はRepositoryを通じてドメイン&アプリケーション層から隠蔽しよう!(教科書的発想)
- 問い合わせ条件を上手に取り扱いたい場合はSpecificationパターンが便利だよ!
- とはいえ、小〜中規模システムならEloquentをドメインモデル化した方がコストメリット的に有利なことも事実(小声)
- 「そもそもフルスペックのDDDって必要だっけ?」という問いも時には必要
- どうせ使うならLaravelっぽくGlobal Scopeを活用してモデルを細分化しよう!(参考:Laravelでつくる、深くて表現豊かなモデル - Eloquent\Model を継承はするが、テーブルと一対一で対にならないクラス)
オマケ:???「キサマはRubyistを嘗めたッッッ」
「キサマ等のいる場所は既にRailsが2000年前に通過した場所だ!(訳:「マジックビーンズ sql」で検索するとより詳しくこの問題について調べられるよ!)」