8

WCF サービスを使用してデータ ソースと対話する WPF アプリケーションを作成しています。クライアントと WCF サーバーの両方に DI を使用して分離されたコードを確保していますが、バックエンドからユーザー インターフェイスへのデータ転送を処理する方法がわかりません。

レイヤーを別々に保つために、データは現在、いくつかのマッピング手順を介してデータベースから UI に転送されます。サーバー側では、データ エンティティはドメイン オブジェクトにマップされ、ドメイン オブジェクトは再びサービス データ コントラクトにマップされます。クライアント側では、WCF プロキシ クラスがビューモデルにマップされます。

職場の一部の開発者は、変更が導入されたときに非常に多くのクラスを更新する必要があるため、一見同一のクラス間でデータを「コピー」するとメンテナンスの問題が生じると主張しています。代わりに、クライアント アプリケーションと WCF サービスの両方を制御するため、レイヤー全体で共有クラスを使用する必要があると言われています。私も関連する作業量を心配しており、パフォーマンスが低下する可能性があると考えていますが、一方で、レイヤー/抽象化全体で共有クラスを使用すると、密結合が発生する可能性があります。最善のアプローチは何ですか?

4

3 に答える 3

9

DTOをビジネスオブジェクトとして使用することは、最善の決定ではありません。私の経験から、通常、オブジェクトがすべてのレイヤーで同一である場合、おそらくどこかのアーキテクチャに問題があると言えます。

実際のビジネスシナリオでは、サーバー上のビジネスロジックとクライアント上のビジネスロジックが同じコンテキストを持ち、同じオブジェクトで動作することはほとんどありません。そして、それらがデータベースとまったく同じ構造を持っている場合...うーん...データ駆動型アプリケーションのように聞こえます。

しかし、クライアントが一部のデータにアクセスし、それを変更して保存し直すときにデータ駆動型アプリケーションである場合、おそらくこの複雑な階層化は本当に必要ないのでしょうか。シンプルに聞こえるので、シンプルにしましょう。データ駆動型アプリケーションの場合は、データベース上にWCF DataServicesコンテキストを作成し、DTOやマッピングなどを考慮せずにWCF経由でデータにアクセスするだけで、すべての汚い作業を実行できるようにしてください。

データ駆動型アプリケーションでない場合は、サーバー側に複雑なビジネスロジックがある可能性があり、このビジネスロジックは通常、そのコンテキストのみを意味するオブジェクトで動作します。これらのオブジェクトをUIまでプッシュするのは意味がありません。

代わりに、UIは、システムに何かを実行するように要求するために、おそらくサーバーにコマンドを送信します。たとえば、AccountDTOをロードする代わりに、「DisableAccount(id = 123)」コマンドを送信し、IsEnabledフラグをfalseに変更して、プッシュバックします。ビジネスロジックがある場合、アカウント無効にする方法や他のことを行う方法を知る必要のないクライアントからのそのようなコマンドによってトリガーされる可能性があります。それはただ知っていて、システム何かをするように命令することができます。

したがって、このシナリオでは、クライアント(UI)はサーバーと同じオブジェクトを必要としません。ユーザーに表示するためにいくつかのデータが必要になる場合がありますが、ビジネスロジックではなく、クライアントのビューにとって意味のある形式になっていることは間違いありません。おそらく、何らかの形で組み合わされた、いくつかの非正規化されたデータが含まれます。

たとえば、User for UIは、UsersテーブルにマップされたDTOではありません。これは別のDTOであり、さまざまなテーブルのユーザーデータと統計を含み、何らかの方法で処理されます。クライアントはサーバーのデータストレージの内部構造を知る必要がないため、公開する必要はありません。関連するデータを取得し、適切なコマンドを送信します。それだけです。

これをすべて言って、それはあなたが行う二者択一ではないことを強調する必要があります。単純な機能の場合は単純なアプローチを使用でき、ビジネスロジックを持つことが理にかなっている機能の場合は他のことを行うことができます。

すべてに1つを選択する必要はありません。したがって、「The Way」であるという理由だけで、常に3つの類似したオブジェクトを作成する必要はなく、常にエンティティをUIに渡す必要もありません。しかし、あなたしなければならないことは、コンテキストを明確に分離し、どのアプローチが使用されるかを定義することです。

80%では、おそらく単純なもの(WCF DataServicesなど)になり、何もする必要はありません。多くの操作では、データを変更したいだけなので問題ありません。

しかし、実際のビジネスロジックが存在する他の20%(アプリケーションの「コア」)では、オブジェクトだけでなく、レイヤー間の責任についても、この種の分離が必要になる場合があります。

于 2012-02-08T10:49:22.090 に答える
7

そのすべてのマッピングは、実際にメンテナンスの負担を生み出します。それが保証されるかどうかは、構築しているものと、ビジネス ロジックがどれほど複雑かによって異なります。

ただし、レイヤーや層を越えてデータ構造を共有し始めると、アーキテクチャが分離されなくなることを認識することが非常に重要です。それを行うと、本質的にモノリシック アプリケーションを構築することになります。誤解しないでいただきたいのですが、モノリシック アプリケーションを作成するのは、栄光に満ちた CRUD アプリケーションを作成するだけであれば、何も問題はありませんが、その決定を明示的に行うことが不可欠です。

少なくともこれらの選択肢があります:

  • 厳密なレイヤリングを維持します。マッピング コストは残りますが、コードは分離されます。
  • モノリシック アプリケーションを構築します。折りたためるものはすべて折りたたむ。できるだけシンプルにしてください。密結合になりますが、単純すぎて問題にならないかもしれません。
  • CQRSアプリケーションや SOA マッシュアップの構築など、根本的に異なることを行います。

個人的には、最近では 3 番目のオプションを好みます。

于 2012-02-09T23:08:20.303 に答える
0

層について神聖なことは何も見ていません。モデル内のすべてのエンティティのレイヤー固有のバージョンを持つと、クラスの数が大幅に増加します。私の見解では、それは不要です。それは DRY の原則に違反しています。なぜ同じことを繰り返し続けるのでしょうか?

層の純度は何をもたらしますか?

したがって、最善のアプローチは、これらのモデル エンティティを恐れずに渡すことだと思います。

于 2012-02-08T10:14:35.260 に答える