質問

おそらくこれが長年の質問であることは承知していますが、より良い方法は何でしょうか?アプリケーションのすべての層でドメイン モデル オブジェクトを使用し、JSP (私は JSF を使用しています) 上で値を直接バインドします。または、ドメイン モデル オブジェクトを DAO またはサービス層の DTO に変換し、軽量の DTO をプレゼンテーション層に送信します。

データベースを変更するとすべての DTO が変更されるのに対し、どこでもモデル オブジェクトを使用すると、影響を受けるモデル オブジェクトを変更するだけで済むため、DTO を使用するのは意味がないと言われました。ただし、DTO の使いやすさと軽量さはそれを上回るようです。

私のアプリは Hibernate モデル オブジェクトを使用し、かつ独自にカスタム作成したモデル オブジェクトを使用していることに注意してください (つまり、どの DB セッションにもバインドされておらず、常に切り離されています)。上記のシナリオのいずれかが、厳密なモデル オブジェクト パターンにとってより有益ですか?Hibernate の使用は、遅延初期化例外などに関して大きな PITA となります。

さらなる議論を期待してこの質問を編集しています(これが正しいかどうかはわかりません)。

モデル オブジェクトに関して私が抱えている問題は、それらがまったく柔軟性がないことです。以下のコメントでは、モデル オブジェクトがすべてのレイヤーで使用できるようにアプリケーションを設計する必要があると述べています。なぜ?ユーザーがばかばかしい機能を望んでいる場合、「それはモデル オブジェクトでは機能しません」と伝えるべきでしょうか?

単純明快ですが、モデル オブジェクトが機能しない場合があります。次のような場合があります。

public class Teacher {
    List<Student> students;
    [tons of other Teacher-related fields]
}
public class Student {
    double gpa;
   [tons of other Student-related fields]
}

しかし、そのすべての情報は必要ないかもしれません。必要なのは、教師の姓、今年教えている生徒の数、および全生徒を合わせた平均 GPA だけです。その場合、あなたならどうしますか?教師の完全な情報と生徒の関係を取得し、コードで生徒のリストのカウントを取得し、内部のすべての GPA の合計平均を計算しますか?これは、単純に「String lastName」、「int numStudents」、「double combinedGpa」を使用して DTO を作成するよりもはるかに手間がかかるように思えます。

これらについてはすでに決まっているように聞こえるかもしれませんが、モデル オブジェクトをあらゆるインスタンスで完全にクリーンに使用できるアプリケーションをまだ開発したことがありません。常軌を逸したユーザー要求を持つ通常の現実世界のアプリケーションは、そのようには機能しません。

役に立ちましたか?

解決

それは実際にはアプリケーションの複雑さによって異なります。ドメイン オブジェクトをビュー レイヤーに混在させると、次の 2 つの影響が考えられます。

  1. ビュー レイヤーに必要なものを収めるためにドメイン オブジェクトを変更したくなるでしょう。
  2. ビュー レイヤーには、ドメイン オブジェクトが提供するものとビューが実際に必要とするものとの間の不一致によって生じる余分な複雑さが含まれます。この複雑さを回避することはできないかもしれませんが、おそらくビュー レイヤーには属していません。

ドメイン オブジェクトが単純でビューが少ない場合は、DTO をスキップするのが最も簡単な方法かもしれません。

一方、ドメイン モデルが進化して複雑になる可能性があり、ビューが多数で多様になる可能性がある場合は、ビュー固有のオブジェクトを用意するのが良い考えかもしれません。MVC の世界では ViewModel を使用するのが一般的であり、私にとっては非常に理にかなっています。

他のヒント

ドメイン オブジェクトにもう一度投票します。ドメイン駆動設計に関する限り、ドメイン モデルが王様であり、可能な場合には使用する必要があります。アプリケーションは、ほとんどの層 (インフラストラクチャ層を除く) がドメイン オブジェクトを使用できるように設計する必要があります。

私は、DTO はオブジェクトをシリアル化する必要がある場合にのみ役立つと考えています。有線または互換性のないアーキテクチャへの転送がない場合は、それらを使用しません。DTO パターンは、シリアル化をドメイン オブジェクトから遠ざけるのに役立ちます。UI/ドメインの対話にはシリアル化が必要ないことを考慮して、単純にして実際のオブジェクトを使用してください。

DTO を持つことは一般的にアンチパターンではないと思います。多くの人やシステムがそれらを使用しており、ドメイン モデルから独立して設計およびモジュール化できる分離されたビュー レイヤーが得られる利点があります。可能な限りドメイン オブジェクトを使用するべきであるという意見には同意しますが、ビュー レイヤーをドメイン モデルに直接結び付けると問題が発生する可能性があるシナリオがあります。

私は、ドメイン オブジェクトをラップするだけでほとんどの操作をそれらに委任するビュー モデルで良い経験を積んできました。これにより、ビューとドメイン層が分離され、ドメイン オブジェクトの柔軟な構成が可能になり、IDE がサポートしているため、実装する作業はまだそれほど多くありません。委任パターン。

ドメイン オブジェクトの送信に問題がある場合のシナリオ:

  1. UI レイヤー (例: Flex / GWT) に送信される集計情報または他のタイプの「計算フィールド」が必要な場合があり、ドメイン オブジェクトを台無しにしたくない場合があります。
  2. 循環オブジェクトグラフをシリアル化する必要がある場合があります(例では、Studentにリスト関係がある場合)。一部のプロトコルにはそれに関する問題があります。
  3. フレームワーク シリアライザー (flex 用の blazeDS / GWT シリアライザー) を処理するときの Hibernate LazyInitializationException

そのような状況ではそれが明確な答えであるかどうかはわかりません

私の意見では、すべての層でドメイン モデル オブジェクトを使用することにまったく問題はありません。すべての情報は必要ないと言いました。JSP を使用するときは、必要なデータのみを使用してください。誰もあなたにすべての財産を取得するように強制しているわけではありません。また、GPA、学生数などを取得するには、オブジェクトのプロパティに関連する計算を行う必要があるとも言いました。3 つのオプションがあります:ドメイン モデル オブジェクト内に適切なデータを返す合成プロパティを作成し、適切にまとめます。コントローラー層またはサービス層で計算を実行し、適切なゲッターを通じてそれらを公開します。または、すべてを JSP 内で処理します。いずれにしてもデータを取得、コンパイル、ラングリングする必要があるのに、DTO を使用してさらに複雑にする必要はありません。

さらに、各 DTO では、a.) 保守する必要がある追加のクラス、および b.) DTO を構築して設定するクラスのどこかに少なくとも 1 つの追加のメソッド (DAO、ファクトリ メソッドなど) を作成することになります。 。メンテナンスの増加 = 6 か月後の開発者の不満。

したがって、DTO に対する私の主張は次のとおりです。私はそれらを使用しますが、速度やメモリ使用量を最適化する必要があり、完全なドメイン モデル オブジェクトをハイドレートするコストが高すぎる場合など、特定のシナリオでのみ使用します。Web サービスは、DTO を使用することを好む場合の良い例です。

クラスの動作やその内部メソッドは、その動作に関係のない層に公開すべきではありません。動作ではなくデータを転送します。ドメイン内でドメイン オブジェクトを使用します。Web は管理されたドメインではないため、UI 開発者はドメインの動作を気にする必要はなく、データだけを気にする必要があります。

ドメインはカプセル化され、ドメインの健全性に関係のない者による変更から保護される必要があります。

漏れ行為は最良の習慣ではありません。

小規模なプロジェクトの場合は、正しい原則に従ってビルドしてください。そうすることで、私たちは、どのように行うかだけではなく、なぜそれを行うのかを常に念頭に置きます。

ここでまず考えるべきは、新たなレイヤーを導入するコストだと思います。DTO を例に挙げます。そのためにはマッピングが必要です。誰かが言ったように、翻訳は悪であり、可能な限り避けるべきです。

一方で、一般的にやってはいけないことはほとんどないと思います。すべての DTO が悪であると言う人は間違いです。それは常にユースケースによって異なります。彼らは本当に正当化されているのでしょうか?

最後に、私は個人的に、ドメイン オブジェクトをビュー自体に解放すべきだと考えています。ウィケットの統合がどのようなものになるかを想像してみてください。しかし、Spring MVC を例にとると、ドメインはおそらくアプリケーション層に残るでしょう...

現在、DTO はアンチパターンであると広く考えられており、通常は「何としてでも避けてください」というアドバイスが行われます。

Hibernate のような ORM フレームワークの主な利点の 1 つは、ドメイン オブジェクトをすべてのレベルで使用でき、実際には DTO を必要としないことです。もちろん、注意しなければならないのは、それらの関係について考えるために時間を割く必要があるということです。遅延フェッチをいつ使用するか、いつイーガーを使用するかなど。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top