ビジネスオブジェクトごとにモデルを作成するというダイムの答えにほぼ同意します。ビジネスが解決しようとしている問題は、モデルクラスの作成方法を促進するはずです。実際には、テーブルごとに1つのモデルを作成することから始めるのがよいことがわかりました。適切に設計されたスキーマは、アプリケーションコードでモデル化する必要があるビジネスプロセス(ドメインモデルとも呼ばれる)を模倣している可能性があります。
オブジェクト/リレーショナルマッピングレイヤーを使用すると、ドメインモデルにデータベーススキーマと同じ関係が含まれ、データアクセスレイヤーを繰り返し呼び出す必要がなくなります。Eloquent for PHPを例として確認してください。スキーマとドメインモデルはどちらも、ビジネスプロセスをサポートするように設計する必要があります。
これは、Marjan Venemaの回答の最初の部分につながります。
テーブルごとのモデルは、クラス構造でデータベースを再作成しているだけだと言います。これは貧血モデルとして知られており、アンチパターンと見なされています。
アン貧血ドメインモデルは、アンチパターンです。Venemaが示唆する「テーブルごとのモデル」は「データベースの再作成」と見なすことができますが、これだけが貧血ドメインモデルであると言うのはまったく正しくありません。
マーティン・ファウラーから:
Anemic Domain Modelの基本的な症状は、最初は赤面することで本物のように見えることです。ドメイン空間には名詞にちなんで名付けられたオブジェクトがあり、これらのオブジェクトは、真のドメインモデルが持つ豊富な関係と構造に関連付けられています。動作を確認すると問題が発生し、これらのオブジェクトには動作がほとんどないことがわかり、ゲッターとセッターのバッグにすぎません。
(強調、私の)
貧血ドメインモデルの重要な要素は、ドメインモデルクラスの動作またはメソッドの欠如です。
これは、クラスがデータと動作の両方を持つことを目的としているためです。モデルを単一のテーブルに制限する場合、複数のテーブルのデータと動作を処理する必要があるコード(動作)をどこに配置しますか?
ここでも、ドメインモデルが1つのテーブルにしかマッピングされていない場合でも、ドメインモデルに動作を設定できます。複数のテーブルに影響を与える動作は、実際には複数のテーブルにマッピングされる複数のオブジェクトに影響を与えます。ドメイン駆動設計は、Venemaが述べたまったく同じ問題へのアプローチです。「複数のテーブルからのデータと動作を処理する必要があるコード(動作)をどこに置くのですか?」
そして答えはAggregate Rootです。マーティンファウラーは次のように述べています。
集計は、ドメイン駆動設計のパターンです。DDDアグリゲートは、単一のユニットとして扱うことができるドメインオブジェクトのクラスターです。例としては、注文とそのラインアイテムがあります。これらは別々のオブジェクトですが、注文を(そのラインアイテムと一緒に)単一の集計として扱うと便利です。
(強調、私の)
「ドメインオブジェクトのクラスター」は、「複数のテーブルにマップするドメインモデル」と見なすこともできます。複数のテーブルに影響を与える動作は、集約ルートで定義する必要があります-複数のテーブルまたはオブジェクトに影響を与える「もの」をカプセル化するクラス:
もう一度、マーティン・ファウラーから:
集合体には、単純なフィールドとともに、複数のコレクションが含まれることがよくあります。
OPの元の質問に答えるには:
...データベーステーブルごとにモデルを作成することをお勧めしますか?そうすれば、メソッドが2回記述されることはありません。
ここから始めるのが良いと思いますが、スキーマとオブジェクトモデルが100%一致している必要はないことに注意してください。オブジェクトモデルは、ビジネスルールの実装と適用にもっと注意する必要があります。スキーマは、ビジネスデータをモジュール化されたスケーラブルな方法で格納することに、より重点を置く必要があります。
ビューモデルと呼ばれるモデルの変動はあるものの、コントローラごとのモデルは、良い習慣ではないでしょうないコントローラー層にフィット。A ビューモデルは、ディスプレイの特定の種類に合わせてGUIアプリケーション内のWebページまたはフォームであることをドメインモデルの再編です。