MVC:ビジネスロジックをどこに置くか?[閉まっている]


81

まず第一に、私はこれについて多くの質問を見てきましたが、その背後にある十分な理由はありません。私の質問が十分ではなく、削除する必要がある場合は、理解します。

私は、を見て撮影している例えば、これと45+は答え、彼はかなり論理的に聞こえるモデルにビジネスロジックを置くことを知らせる言うまで投票しました。

ただし、最初の大規模なプロジェクトでは、すべてのBLをコントローラーで完全に実行しました。これらのことについては質問せずAccountController、フォーム認証付きのMVCを選択した場合に自動的に追加されるでどのように実行されるかを確認したためです。すべてのメソッドはBLでかなり詰め込まれているように見えます。それとも、追加できるコードの量が最も少なく、見落としているのでしょうか。

YouTubeの人が、すべてのロジックをモデルに組み込んで正しいかどうかを尋ねましたが、最初はそうではありませんでした。それから私は彼が正しいのではないかと思い始めました!?

それで、結局のところ、私は私のビジネスロジックをどこに置くのですか?それがモデルクラスにある場合、コントローラーにあるメソッドでどのくらいのコードを正常な量と見なす必要がありますか?コントローラーのモデルからメソッドを呼び出してからビューに戻るための1行ですか?


1
ビジネスロジックはコントローラに入ります。モデルロジックはモデルに入ります。モデルロジックは、モデルを具体的に/のみ扱うものです。セッター/ゲッター/プロパティ/アダー/リムーバーなど
2013

1
@crush:同意しません。私が読んだように-「モデルオブジェクトはアプリケーションのデータと「ビジネスロジック」を保持します。」と「コントローラーオブジェクトはモデルとビューオブジェクトを結び付けます。」
ChiefTwoPencils 2013

@ BobbyDigital-ソースへのリンクを提供できますか?:)
AndriusNaruševičius

確かに、それはビッグナードランチガイドの適切なMVCの使用法の説明にありますが、残念ながら、これを確認するために本を購入する必要があります。
ChiefTwoPencils 2013

ただし、C#の本でこれを確認しようとしたところ、asp.netでは、ビジネスロジックは中間層に移動します。中間層はUI、中間はコントローラー、下部はデータベースになります。しかし、彼らはMVCについて具体的/明示的に話しているわけではありません。これはプログラマー向けのC#からのものです:)
ChiefTwoPencils 2013

回答:


55

いくつかの理由から、モデルにドメインロジックを配置することを好みます。

  1. モデルにはUIコードが含まれていないため、テストが簡単です。可能な限り、UIコードを作成する前に、完全に機能する(完全なテストカバレッジを意味する)モデルが必要です。コントローラは、モデルが正しいことを実行していることを信頼し、UIの問題に対処するだけです。

  2. ドメインロジックをコントローラーに配置すると、異なるアプリ間、または異なるコントローラー間でさえ共有するのは簡単ではありません。


2
はい、#2コントローラー間で共有するのが難しい(静的などの方法を使用する必要があった)ので、本当に気に入りました!
AndriusNaruševičius

はい@AndriusNaruševičius、そうしないでください。他のコントローラーに依存せずに、依存関係をコントローラーに注入してみてください。
マークウォルシュ

この回答は、ASP.Net MVC「モデル」(MVVMパターンの一部)とは無関係な「ドメインモデル」(従来のMVCパターンのM部分)について話していると思います。
Alexei Levenkov 2014年

1
では...複数のモデルに依存するロジックをどこに配置しますか?
コロブキャニオン

1
@Ferrucioそれは悪い解決策です。作成される他のオブジェクトに依存するオブジェクトを作成する「依存関係地獄」に行き着きます。不要な/未使用のデータが理由もなく渡されるため、これは悪い解決策です。関数が仕事を成し遂げるために必要なものだけを受け取るようにしたいのです。そうしないと、コードがすぐに不明確になります。より良い解決策は、構築に最低限必要なビジネスロジッククラスを作成することです(または、さらに良いことに、依存性注入を使用して構築します)。そうすれば、ビジネスロジックを実行するためにいくつかの無関係なオブジェクトをフェッチする必要がなくなることはありません。
コロブキャニオン

43

モデルをクリーンに保つのが好きです。つまり、プロパティだけでビジネスロジックはありません。私は常に依存関係をコントローラーに注入するのが良いと思います。これらの依存関係には、モデルで実行するロジックが含まれています。私は可能な限り単一責任の原則に従うのが好きで、たくさんのメソッドを持つモデルはすぐに肥大化することがわかります。両方に長所と短所があります。多くの依存関係を注入することにはオーバーヘッドがありますが、単独でテストすることができ、クラスを単純に保つことができ、最終的にはよりスリムなコントローラーになります。私のロジックはクラスのメンバーとしてモデルに実際には存在しませんが、それでもビジネスロジックです。Httpcontextのようなモックは少し悪夢で不必要なので、コントローラーでビジネスロジックを定義しない傾向があります。


5
+1は完全に同意します。モデルの責任を最小限に抑えるのが好きなのは私だけだと思いました!
リー

1
確かに、彼は私のログインコントローラーの要点ですgist.github.com/markwalsh-liverpool/8fb361a9df0dcf034caf
Mark Walsh

1
では、ロジックをモデルやコントローラーに配置しない場合、どこに配置しますか?
niico 2017年

1
コントローラのコンストラクタに引数をどのように渡しますか?通常、コントローラーの初期化は舞台裏で行われますか?
ジェフ

1
依存性注入を使用します。
マークウォルシュ

23

ビジネスロジックは、問題のドメインに属していると、問題のドメインに属しているすべてのものは、に行くモデルMVCインチ

コントローラは、ビューに、ビューの背面からモデルへのモデルからのデータを渡すための責任を負わなければなりません。したがって、コントローラーは、ユーザーが操作するものと、プログラムが問題の状態をモデル化して保存する方法との間の架け橋になります。配管、いわば。

ここで重要なのは、ビジネスロジックと配管ロジックの違いです。私の意見では、自動生成されたアカウントコントローラーが行うことは、ほとんどが配管であり、実際にはビジネスロジックではありません。配管ロジックは必ずしも短いとは限らないため、人為的な制限を課す必要はありません(「コントローラーで最大X回の呼び出し」など)。


私はこれすべてに同意します。ただし、特にEFを使用して、モデル内のクラスを構造化する方法から多くの混乱が生じると思います。IE:部分クラスを使用して、さまざまなC#ファイルでロジックを構築していますか?EF用に1つのファイル、ロジック用に1つのファイル?
S1R-Lanzelot

13

私のチームは、webforms(asp.net)からmvcに移行したときに多くの調査を行い、次の構造を考え出しました。私によると、アプリケーションの大きさや小ささについてではありません。コードをクリーンでクリアに保つことについてです。

DALProject

AccountsDAL.cs --- > Calls SP or any ORM if ur using any

BLLProject

AccountsBLL.cs ---> Calls DAL

WebProject

Model
    AccountsModel --- > Contains properties And call BLL
Controllers
    IndexController ---> Calls Models and returns View
Views
    Index

コントローラーは、モデルとビューの間で受け渡されるデータを担当する必要があります。それ以外は、不要なコードがあってはなりません。たとえば、ログを記録する場合は、コントローラーではなくモデルレベルで実行する必要があります。


13

このトピックに関しては混乱があるようです。ほとんどの場合、MVCパターンをN層アーキテクチャと混同する傾向があるようです。現実には、2つのアプローチを一緒に使用できますが、一方は他方に依存せず、どちらも必要ありません。

N層アーキテクチャは、アプリケーションを複数の層に分離することに関係しています。簡単な例は、アプリケーションがプレゼンテーション層、ビジネスロジック層、およびデータアクセス層に分割されている場合です。

MVCは、アプリケーションのプレゼンテーション層を扱うデザインパターンです。ビジネスロジックとデータアクセスロジックをプレゼンテーション層から分離することなく、MVCアプローチに従ってアプリケーションを設計することは完全に可能であり、最終的には単一層の設計になります。

その結果、アプリケーションを層に分割せずにMVCアプローチに従っている場合、ビジネスルールとデータアクセスロジックのビットが残りのロジックと混合されたモデル、ビュー、およびコントローラーになってしまいます。

定義上、N層アーキテクチャでは、プレゼンテーション層はビジネスロジック層とのみ通信できると想定されているため、MVCコンポーネントはビジネスロジック層とのみ通信できるようにする必要があります。

プレゼンテーションを含まない、つまりプレゼンテーション層を含まないアプリケーションを構築している場合は、MVCパターンを気にする必要はありません。ただし、プレゼンテーション層が含まれていなくても、アプリケーションを複数の層に分割して、N層の設計に従うことができます。


8

一般的に言って、ビジネスロジックはMVCプレーヤーのいずれにも存在すべきではありません。それは消費されるべきですコントローラのアクションによってがあります。

多くの人が言及しているように、クライアントに依存しない再利用可能なコンポーネントのセットとしてビジネスロジックをホストするライブラリを作成するのが最善です。

このようにすると、ソフトウェアの再利用性、互換性、スケーラビリティ、およびテスト容易性が大幅に向上します。また、特定のフレームワーク機能への依存を減らし、新しい/異なるテクノロジーへの移行を容易にします。

ビジネスロジックをスタンドアロンのアセンブリ(または複数のアセンブリ)に抽象化することは、長年にわたって私たちに役立ってきました。私たちのビジネスロジックは、事実上すべての.NETテクノロジ(ASP.NET MVC / API / Core、WPF、Win Forms、WCF、UWP、WF、コンソールなど)で使用できます。

さらに、中間層がビジネスルールと検証ロジックを処理して、.NETMVCフレームワークへの依存を減らすことができます。たとえば、.NET MVC検証ヘルパーの使用を避け、代わりに独自のヘルパーに依存します。これは、.NETテクノロジからビジネスロジックを簡単に利用できるようにするもう1つの要素です。

このように中間層を論理的に設計することで、この物理アーキテクチャを簡単に実現できます。

ここに画像の説明を入力してください

それはPeasy.NETで書かれ、年にもわたって私たちに役立ってきました。実際、私たちはそれをオープンソース化することに決めました。

中間層がどのように見えるかについて誰かが興味を持っている場合は、クライアントにとらわれないビジネス層のサンプルを次に示します。また、複数の.NETクライアント(ASP.NET MVC、Web Api、およびWPF)による消費についても説明します。

これが誰かを助けることを願っています!


ほとんどの場合、ロジックを再利用する必要はありません。WebAPIにASP.NETCore MVCを使用することにした場合、WPFまたはWinFormsでそのビジネスロジックを使用することは決してありません。とにかくクライアントはサーバーと通信するからです。ビジネスロジック、特にデータベースアクセスロジックをクライアント側に配置するのは悪いことです。
コンラッド

追加する層が多いほど、保守性とテスト性が低下すると思います。結局、統合テストはもっと重要です。
コンラッド

8

ビジネスロジック、モデルビューまたはコントローラーに配置しないでください。別のビジネスロジック層が必要です。この層の唯一の目的は、ビジネスロジックを処理することです。これは、SOLIDとより一致しています。

ビジネスロジックをMVまたはCに配置すると、テスト/再利用が難しいコードになってしまいます。

モデルにロジックを配置するのはどうですか?

それは悪い解決策です。

オブジェクトがオブジェクトに依存している依存関係地獄に行き着きます。 ここに画像の説明を入力してください

完全に単純な関数がある場合でも、それを呼び出すにはすべての依存関係を満たす必要があります。

また、原因となり、不要未使用データが理由もなく周りに渡されます。これは、パフォーマンスの低下によってはパフォーマンスにも影響を与える可能性があります。

また、単純な関数をテストするためだけに複数のオブジェクトをモックする必要があるため、単体テストはa **で苦痛になることにも言及する必要があります。

適用可能なクリーンコードの原則

  1. クラス/関数は、仕事を成し遂げるために必要なものだけを取ります。
  2. 関数は、可能であれば3つ以下のパラメーターを取る必要があります
  3. クラス/関数/変数にインテリジェントに名前を付けます(Microsoftの標準に従います)
  4. ビジネスロジックをモデルビューまたはコントローラーに結合しないでください

コントローラー

コントローラでは、依存性注入を使用してビジネスロジック層注入できるはずです。コントローラが情報をビジネスロジック層にルーティングするためにのみ使用されていることを確認してください。コントローラには、ビジネスロジックを直接含めるべきではありません。検証はすべてIValidatable、モデルで処理する必要があります。すべてのビジネスロジックは、別のレイヤーにルーティングする必要があります。


ここで私が働いている場所にはビジネス層があり、それがないことだけが欲しかったのです。ビジネスレイヤーは純粋な混乱であり、ロジックはモデル内にあるはずです。
マテウスフェリペ

@MateusFelipeでは、複数のモデルを必要とするロジックをどこに配置しますか(例:支払いと製品)?あなたは持っている新しいモデルの作成でくださいPaymentProductインスタンス変数としての?そのオブジェクトの名前は何ですか?モデルがビューで使用されていない場合、そのモデルはモデルではなくなります。これは別のレイヤーの一部です。理想的には、あなたが作るそのクラスは、それが仕事を成し遂げるためにそれが支払いと製品から必要なものだけを取るべきです。とだけが必要な場合は、オブジェクト全体ではなく、これら2つのパラメータのみを使用する必要がproductNameありpriceます。
コロブキャニオン

4

私が持っている一般的な答えは、ビジネスロジックは通常2つのカテゴリに当てはまるということです。

オブジェクト指向ビジネスロジック:(モデル内の)オブジェクトとしてモデル化され、通常はリポジトリとして注入されます。

手続き型ビジネスロジック:コントローラーに挿入できるインターフェイスを備えたサービスを利用します。

コントローラロジック:コマンドを受信して​​モデル/サービスに渡す方法と、それらの結果をビューに渡す方法を制御するロジック。

コントローラにはビジネスロジックがあってはなりません。これは、ユーザーインターフェイスがビジネスロジック(または問題がより手続き的な性質の場合はサービス)を処理するモデルに入力を渡す方法を制御するためのデザインパターンの非常に特殊な部分です。


2

モデルもきれいに保つのが好きです(参照:@Mark Walsh)。コントローラに埋め込まれたロジックを再利用できないという問題は、依存性注入によって簡単に克服できます。または、依存性注入が多すぎると思われる場合は、インターフェイスを介してビジネス/ドメインロジックを公開し、コントローラのファサードパターンを使用します。そうすれば、必要な機能を手に入れることができますが、コントローラーとモデルの両方をきれいに保つことができます。


1

また、モデルをクリーンに保ちたいと思います。MVCコントローラーは、呼び出しを行うためにのみ使用する必要があり、クリーンに保つ必要もあります。したがって、その再利用性、感度、および関連性に応じて、ビジネスロジックを記述できます。

1.WebApiコントローラー:webapiコントローラーを使用する利点は、これらをサービスとして後で他のデバイスに公開して、コードを再利用できるようにすることです。

2. BAL /共通共通:特定の使用法があり、APIとして公開できないロジックがいくつかあり、このクラスでプッシュできます。

3.リポジトリ:データベースに関連するすべてのクエリがリポジトリに追加されます。すべての関数(CRUD操作)を実装する汎用リポジトリー、または各テーブルの特定のリポジトリーが存在する場合があります。実行する操作によって異なります。


1

ahanusaが書いたように、ビジネスロジックを別のDLLまたは別のディレクトリに配置する必要があります。
私はよく、ビジネスロジックを実行するクラスを配置するモデルとコントローラーの同じレベルでLogicsという名前のディレクトリを使用します。
このようにして、モデルとコントローラーの両方をクリーンにします。


0

MVCについての質問であることは知っていますが、私が提供している例(Web API)は役立つと思います。

私は最初のWebAPIを開発しており、他のアプリケーションのビジネスロジックを再利用しています。具体的には、外部DLLから取得されるため、私のAPIは、SAPソリューションと「対話」し、POから要求を受信し、応答を送り返すために使用されます。

ロジック(すでに実装されている)をコントローラーに配置するにはどうすればよいですか?私はそれを必要としません。私のコントローラーは、要求を受信して​​検証し、応答を作成してデータを送り返すだけです。

私はViewModelクラスを使用しており、TransferObjects(外部DLLから取得)から情報を読み取り、ViewModelに変換するために必要なのはマッピング関数だけです。

私は自分のアプリケーション(この場合はWeb API)がビジネスロジックを保持することに不安を感じています。このようにすると、再利用性が失われると思います。

私は自分のビジネスロジックをコントローラーに注入する依存関係として扱っています。

ユニットテスト可能なソリューションを提供するためにレガシーで多くのリファクタリングを行いました。このソリューションを提供するには、多くのインターフェイスを作成し、レガシーにいくつかのデザインパターンを実装する必要がありました。

私の見解では、ビジネス層はアプリケーションの一部、できれば別のクラスライブラリにある必要があります。したがって、アプリケーションに実際の分離の概念が実装されます。

もちろん、CORE(ビジネス)がアプリケーション(API / WebSite)の場合、ビジネスルールはMVCクラスに実装されます。しかし、将来、新しいアプリを開発したいが、いくつかのビジネスルールが同じである場合、両方のアプリケーションに実装された同じロジックを維持するためだけに多くの問題が発生することは間違いありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.