4

正規の Customer ドメイン オブジェクトがあるとします。顧客が表示される 3 つの異なる画面があります: 外部管理者、内部管理者、およびアカウントの更新です。

さらに、各画面には Customer オブジェクトに含まれるすべてのデータのサブセットのみが表示されるとします。

問題は、UI が各画面から (たとえば DTO を介して) データを返すときに、完全な Customer ドメイン オブジェクトのサブセットのみが含まれていることです。したがって、Customer オブジェクトを再作成するためにその DTO を Customer Factory に送信すると、Customer の一部しか得られません。

次に、この顧客を顧客リポジトリに送信して保存すると、そこにないため、大量のデータが消去されます。悲劇が起こります。

問題は、この問題にどのように対処するかです。

私のアイデアのいくつか:

  • 顧客のどの部分を更新するかを示す引数をリポジトリに含め、他の部分を無視する

  • 顧客をロードするときは、静的メモリ、セッション、またはどこにでも保持し、UI から DTO の 1 つを受け取ったら、DTO に関連する部分のみを更新します。

IMO、これらはどちらもクラッジです。他に良いアイデアはありますか?

@chadmyers: ここに問題があります。

エンティティにはプロパティ A、B、C、および D があります。

DTO #1 には、B と C のプロパティが含まれています。

DTO #2 には、C および D のプロパティが含まれています。

UI は DTO #1 を要求します。エンティティをリポジトリから読み込み、DTO #1 に変換し、B と C のみを入力して、UI に渡します。

ここで、UI は B を更新し、DTO を送り返します。エンティティを再作成すると、DTO に含まれているのは B と C だけなので、B と C だけが入力されます。

次に、B と C のみが入力されたエンティティを保存し、A と D を null/空白にします。リポジトリは、A と D を空白として永続的に更新する必要があるかどうか、またはそれらを無視する必要があるかどうかを知る方法がありません。

4

4 に答える 4

4

DTO の受信時に、ファクトリを使用してリポジトリから完全な顧客オブジェクトをロードします。その後、DTO で指定されたフィールドのみを更新できます。

これにより、たとえば、最終更新のタイムスタンプを確認することで、顧客に楽観的な同時実行性を適用することもできます。

于 2008-10-23T21:48:46.447 に答える
3

これはウェブアプリですか?リポジトリから顧客オブジェクトをロードし、DTO から更新して、保存し直します。それは私にはお粗末のようには見えません。:)

更新:更新ごとに(A、B、C、Dの例)

だから私が考えていたのは、エンティティをロードすると、A、B、C、および D が入力されているということです。DTO#1 が B と C のみを更新する場合、それで問題ありません。A と D は影響を受けません (これは望ましい状況です)。

B & C の更新でリポジトリが何をするかは、彼次第です。たとえば、Hibernate/NHibernate を使用している場合は、それを把握して更新を発行するだけです。

DTO #1 に B と C しかないからといって、A と D も無効にする必要があるわけではありません。そのままにしておいてください。

于 2008-10-23T21:43:11.780 に答える
1

リポジトリが (ほとんど排他的に) 非常に豊富なドメイン エンティティを処理することを理解していれば、多数の DTO を簡単にマップ バックできます。

すなわち

dtoUser.MapFrom<In,Out>(Entity)
or
dtoAdmin.MapFrom<In,Out>(Entity)

エンティティなどに dto 情報を戻すには、逆の操作を行います。したがって、リポジトリは豊富なエンティティの多数の DTO のみを保存します

entity.Foo = dtoUser.Foo
or
entity.Bar = dtoAdmin.Bar

entityRepsotiry.Save(entity) <-- do not pass DTO.

DTO の全体的なポイントは、プレゼンテーションのために物事を単純に保つこと、または WCF dataTransfer について言うことです。それは、リポジトリやエンティティとは何の関係もありません。

さらに、DTO からエンティティを構築するべきではありません... エンティティを取得する唯一の 2 つの方法は、それぞれファクトリー (新規) またはリポジトリ (既存) を使用することです。

エンティティをどこかに保存すると言いましたが、なぜこれを行うのですか? それがリポジトリの仕事です。エンティティ(データベース、キャッシュなど)を取得する場所を決定します。他の場所に保存する必要はありません。

ドメインで責任を割り当てるのに役立つことを願っています。それは常に課題であり、あちこちに灰色の領域がありますが、一般的に、これらはリポジトリ、DTO などの典型的な使用法です。

于 2009-05-25T00:12:12.297 に答える
1

この質問は、設計の観点からは意味がないと思われるいくつかのことに基づいているため、最初はこの質問の要点を見逃していました。

  1. リポジトリからエンティティをハイドレートしてから DTO に変換するのは、労力の無駄です。DAL が DTO をリポジトリに渡し、リポジトリがそれを完全なエンティティ オブジェクトに変換すると仮定します。したがって、それを DTO に戻すのは無駄に思えます。

  2. 大量のレコードを表示し、エンティティ データの一部のみを表示する検索結果ページがある場合、複数の DTO を持つことは理にかなっています。その場合、そのページに必要なデータだけを渡すと効率的です。部分的なデータを含む DTO を CRUD ページに渡すことは意味がありません。完全な DTO または完全なエンティティ オブジェクトを与えるだけです。すべてのデータを使用しなくても問題ありません。

その主な問題は、部分的な DTO を使用してこれらのページにデータを渡す必要があるとは思わないことです。完全な DTO を使用した場合、保存アクションが実行されるたびに次の 3 つの手順を実行します。

  1. 完全な DTO をリポジトリまたはデータベースから取得します
  2. フォームを介して行われた変更で DTO を更新します。
  3. 完全な DTO をリポジトリまたはデータベースに保存します

この方法では追加の db ヒットが必要ですが、CRUD フォームではそれほど大きな問題ではありません。

于 2009-02-10T04:47:58.517 に答える