87

まず、誰かがだまされて悲鳴を上げる前に、私はそれを簡単なタイトルに要約するのに苦労しました。別のタイトルは、「ドメインモデルとMVCモデルの違いは何ですか?」だったかもしれません。または「モデルとは何ですか?」

概念的には、モデルはビューとコントローラーによって使用されるデータであると理解しています。それを超えて、モデルを構成するものについては多くの異なる意見があるようです。ドメインモデル、アプリモデル、ビューモデル、サービスモデルなどとは何ですか。

たとえば、リポジトリのパターンについて最近尋ねた質問で、リポジトリはモデルの一部であると空白で言われました。ただし、モデルは永続性モデルおよびビジネスロジック層から分離する必要があるという他の意見を読みました。結局のところ、リポジトリパターンは、具体的な永続化メソッドをモデルから切り離すことになっているのではないでしょうか。他の人々は、ドメインモデルとMVCモデルの間に違いがあると言います。

簡単な例を見てみましょう。MVCデフォルトプロジェクトに含まれているAccountController。含まれているアカウントコードの設計が不十分である、SRPに違反しているなど、いくつかの意見を読みました。MVCアプリケーションの「適切な」メンバーシップモデルを設計する場合、それは何でしょうか。

ASP.NETサービス(メンバーシッププロバイダー、ロールプロバイダーなど)をモデルからどのように分離しますか?それともあなたはまったく?

私の見方では、モデルは「純粋」であり、おそらく検証ロジックを備えている必要がありますが、ビジネスルール(検証以外)から分離されている必要があります。たとえば、新しいアカウントが作成されたときに誰かにメールを送信する必要があるというビジネスルールがあるとします。私の見解では、それは実際にはモデルに属していません。それで、それはどこに属しますか?

誰かがこの問題に光を当てることを気にしていますか?

4

4 に答える 4

69

私がそれを行った方法-そしてそれが正しいか間違っていると言っているわけではありませんが、私のビューを持ってから、私のビューに適用されるモデルを持っていることです。このモデルには、データの注釈や検証ルールなど、私の見解に関連するものだけが含まれています。コントローラには、モデルを構築するためのロジックのみが格納されています。すべてのビジネスロジックを収容するサービスレイヤーがあります。私のコントローラーは私のサービスレイヤーを呼び出します。それを超えて、私のリポジトリレイヤーがあります。

私のドメインオブジェクトは別々に格納されています(実際には、独自のプロジェクトにあります)。それらには、独自のデータ注釈と検証ルールがあります。リポジトリは、データベースに保存する前に、ドメイン内のオブジェクトを検証します。ドメイン内のすべてのオブジェクトは、検証が組み込まれている基本クラスから継承するため、リポジトリは汎用であり、すべてを検証します(基本クラスから継承する必要があります)。

2セットのモデルを持つことはコードの重複であると考えるかもしれません、そしてそれはある程度です。ただし、ドメインオブジェクトがビューに適していない場合は完全に合理的です。

適切な例は、クレジットカードを使用する場合です。支払いを処理するときにcvvを要求する必要がありますが、cvvを保存できません(これを行うには50,000ドルの罰金が科せられます)。ただし、住所、名前、有効期限の変更など、クレジットカードを編集できるようにしてほしいと思います。しかし、あなたはそれを編集するときに私に番号やcvvを与えるつもりはありません、そして私は確かにあなたのクレジットカード番号をページにプレーンテキストで入れるつもりはありません。私のドメインには、新しいクレジットカードを保存するために必要なこれらの値がありますが、私の編集モデルにはカード番号やcvvさえ含まれていません。

非常に多くのレイヤーのもう1つの利点は、正しく設計されていれば、構造マップまたは別のIoCコンテナーを使用して、アプリケーションに悪影響を与えることなくピースを交換できることです。

私の意見では、コントローラーコードはビューを対象としたコードのみである必要があります。これを表示したり、非表示にしたりします。サービスレイヤーには、アプリのビジネスロジックを格納する必要があります。すべてを1か所にまとめておくのが好きなので、ビジネスルールを簡単に変更したり微調整したりできます。リポジトリレイヤーは比較的ダムである必要があります。ビジネスロジックがなく、データをクエリしてドメインオブジェクトを返すだけです。ビューモデルをドメインモデルから分離することにより、カスタム検証ルールに関してはるかに柔軟性があります。また、すべてのデータを非表示フィールドのビューにダンプして、クライアントとサーバー間で前後にプッシュする(またはバックエンドで再構築する)必要がないことも意味します。

<% if (!String.IsNullOrEmpty(Model.SomeObject.SomeProperty) && 
    Model.SomeObject.SomeInt == 3 && ...) { %>

すべてが分散して重なっているように見えますが、このように設計することを目的としています。完璧ですか?あまり。しかし、コントローラーからリポジトリーを呼び出し、コントローラー、リポジトリー、およびモデルにビジネス・ロジックを混在させるという過去の設計よりも、私はそれを好みます。

于 2010-12-30T20:08:00.777 に答える
17

ビュー(ページ)、コントローラー、サービス、およびデータオブジェクト(モデル)がある従来のWebアプリケーション構造にMVC要素がどのように正確に適合するのか疑問に思うことがよくあります。あなたが言ったように、それの多くのバージョンがあります。

「貧血ドメインモデル」(主張されている)-アンチパターンを使用する、上記の広く受け入れられているアーキテクチャのために、混乱が存在すると思います。貧血データモデルの「反パターン性」についてはあまり詳しく説明しません(ここで説明するための私の努力を見ることができます(Javaベースですが、どの言語にも関連します))。しかし、要するに、それは私たちのモデルがデータのみを保持し、ビジネスロジックがサービス/マネージャーに配置されることを意味します。

しかし、ドメイン駆動型アーキテクチャがあり、ドメインオブジェクトが期待どおりであり、状態ロジックとビジネスロジックの両方を備えていると仮定しましょう。そして、このドメイン主導の視点では、次のことが起こります。

  • ビューはUIです
  • コントローラはUIの入力を収集し、モデルのメソッドを呼び出して、UIに応答を返します。
  • モデルは私たちのビジネスコンポーネントであり、データを保持するだけでなく、ビジネスロジックも備えています。

私はそれがあなたの主な質問に答えると思います。リポジトリレイヤーのように、さらにいくつかのレイヤーを追加すると、事態は複雑になります。モデルに配置されたビジネスロジックによって呼び出す必要があることがよく提案されます(したがって、各ドメインオブジェクトにはリポジトリへの参照があります)。私がリンクした私の記事では、これは完全なベストプラクティスではないと主張しています。実際、サービスレイヤーがあることは悪いことではありません。ちなみに、ドメイン駆動設計はサービスレイヤーを除外しませんが、それは「薄い」ものであり、ドメインオブジェクトを調整するだけであると想定されています(したがって、そこにはビジネスロジックはありません)。

広く採用されている貧血データモデルパラダイム(良いか悪いか)の場合、モデルはサービスレイヤーとデータオブジェクトの両方になります。

于 2010-12-30T20:07:45.253 に答える
3

私の意見では、

モデル -

ビジネスロジックを含めるべきではなく、プラグイン可能である必要があります(シナリオのようなWCF)。ビューにバインドするために使用されるため、プロパティが必要です。

ビジネスの論理 -

「ドメインサービスレイヤー」に配置する必要があります。これは完全に別のレイヤーです。また、ここにもう1つのレイヤー「アプリケーションサービス」を追加します。

App Servicesはドメインサービスレイヤーと通信してビジネスロジックを適用し、最後にモデルを返します。

したがって、コントローラーはアプリケーションサービスにモデルを要求し、フローは次のようになります。

    Controller->Application Services(using domain services)->Model
于 2010-12-30T20:14:33.117 に答える
2

MVCパターンとAsp.netフレームワークは、モデルがどうあるべきかを区別しません。

MS自身の例には、モデルの永続性クラスが含まれています。メンバーシップがモデルに含まれていることについてのあなたの質問。これは状況によって異なります。モデル内のクラスは何かによって所有されていますか?ログインしたユーザーと表示されるデータの間にリンクはありますか?編集可能な権限システムのデータ部分のフィルタリングはありますか?他の誰かがバックエンドサポートのためにそれまたは何かを見る必要があるので、誰があなたのドメインのオブジェクト部分を最後に更新または編集しましたか?

メールの例も異なります。ドメインの総合馬術や特に総合馬術に精通していますか?メールを送信するための別のサービスはありますか?電子メールを送信する行為はドメインの一部ですか、それともシステムの範囲外のアプリケーションレベルの問題ですか?UIは、電子メールが正常に送信されたかどうかを知る必要がありますか?送信に失敗したメールは再試行が必要ですか?送信された電子メールの内容は、サポートまたはカスタマーサービスの要件のために保存する必要がありますか?

これらのタイプの質問は非常に広範で主観的ですが、私はあなたとあなたに投票したすべての人がこれを理解できるように答えています。

要件/タイムライン/リソースはすべて、システムのアーキテクチャに組み込まれています。収益モデルでさえ効果があります。また、撮影するパターンも考慮する必要があります。DDDは、モデルとしての永続性アプリケーションとは大きく異なり、その間のすべての傾斜は特定のアプリでも有効です。アプリをテストするために撮影していますか?これらすべてに効果があります。

于 2010-12-30T20:09:22.170 に答える