webプログラミングのMVCデザインパターンにおいてモデルとは大体DB(データベース)のテーブルそのものです。しかもモデルとテーブルは1対1のことがほとんどです。これはフレームワークがそう扱った方がやりやすい様に自動生成コマンドやクラス、メソッドを仕込んだり、例を用意しているからというフレームワークの用意した道筋が一因です。これは悪いことでなく実際、簡単なロジックを扱うプログラムならばモデル1つはテーブル1つとした方がシンプルにまとまり直感的なコードで要件を満たすことになり、いいことづくめです。無暗にリポジトリやらエンティティやらの概念を持ち込んで一つのテーブルにアクセスするのに二つ三つもクラスやメソッドを経由させられるより遥かに賢明です。
しかしデータベースのテーブルと1対1だとどうにも収まりが悪い時があります。
例えば、1つのユーザアカウントで様々なサービスの恩恵を受けられるプログラムの時です。こういった時、ユーザは何かを購入する、何かにメールを送る、何かを出品する、ブログを書く、などさまざまな操作をします。これらの操作がある上で、usersテーブルは一つだからモデルはUser一つだけ、とするとUserモデルは大爆発します。こういった時には各処理におけるUserモデルである購入者モデル、メール送信者モデル、出品者モデル、ブロガーモデル、を用意して全てusersテーブルに対応させる様にすることで対応できます。
役割駆動設計で巨大クラスを爆殺する – Qiita
例えば、しょっちゅうまとめて参照されるテーブルがある時です。こういった時は複数のテーブルをselect, joinするクエリを必ず発行するモデルを作ることで対応できます(DB上でview作ってそれを読みこむのもありかも)。エンティティ(参照オブジェクト)の考え方はこういった時、役に立ちます。
【PHP】Adapterパターンであるカラムの値によって大きく振る舞いを変えるテーブルの扱いを多少マシにする – 株式会社シーポイントラボ | 浜松のシステム開発会社
例えば、そもそもDBを参照しないがデータを参照する時です。ある外部サービスから吐き出されたファイルを読みこんで扱う時にはDBに関係ないモデルを用意してファイルの情報を持たせる様にするべきでしょう。
【Laravel】データベースと無関係のEloquentっぽいモデルを作るためのFluentクラス – 株式会社シーポイントラボ | 浜松のシステム開発会社
例の様に単にデータを扱うモデルを考えるだけでも、こういった複雑な時にはテーブルと1対1になるモデル以外のモデルを作った方がやりやすいです。
原義に基づくならばMVCのモデルとは”業務領域のデータと振る舞い”です。データベース設計が優れていてそれで設計が完結できる時は、モデル=DB関連の操作をまとめたモノとするのが正しいし適した形ですが、DB上で扱うとどうにも複雑になる時は”振る舞い”も別途モデル化するのが良いでしょう。
余談ですが、振る舞いのモデル化はサービス化です。振る舞いの含意は広い為、多くの動作がサービスと言えなくもないです。サービスと定義できるからと何でもかんでもサービス化すると、オブジェクト指向を実現するためのMVCなのにオブジェクト指向から離れて手続きプログラミングと化します。なるべくサービスにせず、より適した場所を見つけたいものです。