1

以前は RIA サービスを使用していましたが、現在 Breeze Sharp をテストしています。

RIA と Breeze は、サーバー/中間層で見られるものがクライアントで見られるものであるという印象を与えます。それをサポートするために、エンティティという用語がクライアントとサーバーの両方で使用されています。それは本当にエンティティですか、それともクライアント上のプレゼンテーション モデルまたはモデルですか?

1 つまたは 2 つのレベルのエンティティ グラフを持つ小規模なシステムの場合、クライアントとサーバーの両方が同じであると考えても問題はありません。グラフが 5 ~ 6 レベルに及ぶ大規模なシステムでは、エンティティを DTO に変換して単純化する必要があります。UI にエンティティ用の CRUD 画面がない限り、大規模なアプリケーションでは DTO が多くなり、エンティティが少なくなります。ほとんどの場合、これらの DTO は UI が必要とするものを表し、プレゼンテーション モデルと同等です。

クライアントで扱うものをエンティティではなくプレゼンテーション モデルと見なすことができないのはなぜですか?

4

2 に答える 2

15

好きなようにクライアント側のエンティティ クラスを自由に呼び出すことができます :-)

もっと真剣に、これがアンチパターンであるという主張の背後にある典型的な理由を見てみましょう。

クライアントはプレゼンテーション層ではありません

私はこれについて非常に明確にしたい. Breeze は、リッチ Web クライアント アプリケーション用に設計されています。Breeze クライアントはプレゼンテーション層ではありません。プレゼンテーション層あります。また、独自のビジネス モデルとデータ アクセス層も備えています。

「エンティティ」と「DTO」という用語は、人によって意味が異なります。私はPoEAAの「エンティティ」に対するEvan の DDD 定義と「DTO」に対する Fowler の定義が好きです。

Breeze クライアント エンティティは、Evans エンティティと見なさます。Breeze エンティティは単なるプロパティ バッグではありません。ビジネス ロジックもあり、独自のロジックをさらに拡張できます。

Breeze エンティティは「プレゼンテーション モデル」ではありません。これらは、特定の UI 表現から独立しており、通常、プレゼンテーションの問題を実装していません。

これら、ビジュアル コントロールに直接バインドできるように設計されています。これは Breeze の生産性設計上の決定です...エンティティの実装方法に関する決定です。一部の人々 (エンティティのプロパティがアンチパターンであると考える人々) は、それを嫌うでしょう。エヴァンスはその質問について沈黙しています。ファウラーはそれをうんちします。それがあなたを怒らせるなら、あなたはブリーズが好きではないかもしれません. 一緒に移動。

エンティティまたは DTO を送信しますか?

私は、これが誤った二分法であると主張しようとしています。

「エンティティをネットワーク経由で送信するのはアンチパターンだ。常に DTO を送信する」とよく言われます。この不適切な言葉遣いの勅令の背後には、正当な理由があります。クライアントとサーバーのエンティティ クラスが同一の場合、サーバーの実装をクライアントの実装に結合したことになります。サーバーでモデルが変更された場合、クライアントでも変更する必要があり、その逆も同様です。これにより、サーバーとクライアントのコードを個別に進化させる能力が妨げられる可能性があります。私たちはその結合を便宜上の問題として受け入れるかもしれません(そして便宜は重要です!) が、誰もそれを望んでいません.

Breezeクライアントエンティティ クラスは、形状もビジネス ロジックもサーバーエンティティ クラスと同じである必要はありません。Breeze でクエリを実行すると、エンティティ データが送信され、クライアント エンティティに変換されます。保存するときは、クライアント エンティティデータを送信し、サーバー上でそれをサーバー エンティティに変換します。DTO はどちらの方向にも関与する可能性があります。重要な事実は、クラスが異なる可能性があるということです。

もちろん、それらは概念的に関連しています。Customerエンティティの意味が 2 つの側で大きく異なる場合、2 つの表現間でデータを変換するのに非常に時間がかかります。これは、明示的な DTO の有無にかかわらず当てはまります。

クラスが実際には同じである場合、データを双方向に変換する方が簡単であることも認めましょう。異なる場合はマッピング税が発生し、クライアントで Breeze LINQ クエリを作成できなくなる可能性があります。希望すれば納税もできます。ブリーズは関係ありません。

私の傾向は、両側で同じクラスから始めて、必要に応じて変更することです。これは、RIA Services と DevForce のクラスの大部分でうまく機能しています。最も重要なことは、必要が生じたときにクラスを分離するためにリファクタリングすることが決して難しくなかったということです。

<暴言>心配事は、クラス定義を共有するリスクを誇張し、マッピング層のコストを過小評価します。その利点は、アプリケーションの存続期間中に実際に実現されることはめったにありません。</rant>

プレゼンテーション モデルを使用する場合

あなたが書いた:

グラフが 5 つまたは 6 つのレベルに深くなる大規模なシステムの場合、エンティティを単純化するために DTO に変換する必要があります。... ほとんどの場合、これらの DTO は UI が必要とするものを表し、プレゼンテーション モデルと同等です。

私の経験では、クライアントが単にエンティティを画面に貼り付けると仮定した場合にのみ当てはまります。しかし、クライアントはアプリケーションであって、プレゼンテーション層ではないことは既に述べました。

さらに、サーバーにドメイン モデルが必要なのと同じ理由で、クライアントにもドメイン モデルが必要であると主張します。これは、プレゼンテーションとは別に行います。あなたのエンティティは、さまざまなプレゼンテーション ルールに従って、複数の画面に何らかの形で表示されると思います。それは同じモデルで、さまざまな方法で提示されています。これを「データのピボット」と呼びます。

モデルにいくつの顔を配置しても、基礎となるモデル データとそれらを管理するビジネス ルールは同じである必要があります。それが、「プレゼンテーション モデル」ではなく「ドメイン モデル」である理由です。

FWIW、ビューのアクティビティを調整するために、アプリには常に「プレゼンテーションモデル」(別名「ビューモデル」)があります。だから私は「PMかモデルか」と自問自答しません。代わりに、VM の API を介して公開するモデル エンティティにビジュアル コントロールを直接データ バインドするか、いくつのエンティティをラップする中間の「アイテム プレゼンテーション モデル」(別名「アイテム ビューモデル」) にバインドします。どちらに行くかはアプリケーションの決定です。実際には、エンティティに直接バインドすることから始め、必要に応じて「Item ViewModel」にリファクタリングします。

いずれの場合も、クライアントで必要な PM (VM) を構築します。「Item ViewModel」が必要な場合は、クライアントでも作成します。クライアントが表示する DTO の準備をサーバーに依頼しません。サーバーをクライアントに結合するため、これはアンチパターンです

どのように?開発者がクライアントの画面を変更する必要がある場合、誰かがサポートするサーバー エンドポイントと DTO を提供するまで待たなければならない場合があります。変更のきっかけはサーバーの要件ではなく、クライアントの要件でしたが、サーバーとクライアントのリリース スケジュールを調整する必要があります。

サービス汚染

実際にはそれよりも悪いです。サーバー側の開発者の中には、クライアントの要件を満たすために、現在行っていることをやめて、新しいサービス メソッドを追加しなければならない人もいます。それは彼女の要件の 1 つではありませんでしたが、今はそうです。時間が経つにつれて、サービス API は非常に拡大し、すぐに、明らかに同じ仕事をわずかに異なる方法で行う似たようなメンバーでいっぱいになります。

最終的には、誰がどのメソッドを何のために使用しているかを忘れてしまいます。未知のクライアントを破壊することを恐れて、既存のメソッドをあえて変更する人はいません。そのため、開発者は、一見正しいように見えるものをコピーし、少し違うものにして、別の名前を付けます。このサービス API 汚染のパターンは、エンタープライズ アプリケーションを扱ったことがある人なら誰でも知っているはずです。

例外を作る

一見「ルール」と思われるものはすべて、破るためのものです。もちろん、サーバーに表示用のデータを準備させることが適切かつ効率的である場合もあります。これは、データ層でさらに大量の複雑なデータ要約する大量の読み取り専用データで最も頻繁に発生します。私がこの道を行くとき、私は通常、パフォーマンスに関する考慮事項に動機付けられています。それ以外の場合は、エンティティ指向アーキテクチャに忠実であり続けます。

アプリ内のすべてが例外に準拠しているように見える場合、この特定のアプリケーションのアーキテクチャが間違っていると結論付けます...これは Breeze アプリであってはなりません。これがあなたの場合かどうかはわかりません。

お役に立てれば。

于 2014-06-09T22:19:23.777 に答える