ビジネスロジックはコントローラー内にある必要があり、コントローラーは「中間」部分であるため、静的なままであり、モデル/ビューはインターフェースを介してカプセル化する必要があると常に思っていました。そうすれば、何にも影響を与えずにビジネスロジックを変更し、複数のモデル(データベース/ストレージのタイプごとに1つ)と数十のビュー(異なるプラットフォームなど)をプログラムできます。
今、私は この質問では を読みます。ビジネスロジックを常にモデルに挿入する必要があり、コントローラーはビューと深く関係していることを意味します。
私にとって、それは実際には意味がなく、別のデータベース/タイプのストレージをサポートする手段が必要になるたびに、ビジネスロジックを含むモデル全体を書き直す必要があることを意味します。
また、別のビューが必要な場合は、ビューとコントローラーの両方を書き直さなければなりません。
誰かがそれがなぜであるか、または私がどこかで間違った場合に説明してもらえますか?
ElYusubovの答え 主にそれを釘付けにします。ドメインロジックはモデルに、アプリケーションロジックはコントローラーに移動する必要があります。
2つの明確化:
あなたとプログラミングの世界の大部分は、MVCパーツの役割が何であるかを誤解しているようです。要するに、それらは次のとおりです。
モデル =ドメインロジック
ビュー =出力ロジック
Controller =入力ロジック
これは、モデルがビジネスロジック全体を担当することを意味します。画面上でのウィジェットの描画、プリンターの駆動、HTMLとしてのデータの出力、HTTPリクエストの解析などに関連するものはすべて、モデルに属しません。
ただし、最近のいわゆる「MVC」フレームワークの多くは、実際にはMVCをまったく実行しないか、パーツに誤ったラベルを付けます。多くの場合、「モデル」と呼ばれるのはモデルの永続化レイヤーであり、ビジネスロジックは「コントローラー」と呼ばれるものの中にあります。実際のコントローラーは通常、ルーティングテーブルと個々の「コントローラー」内のコードのビットを持つ中央のエントリポイントにすぎず、受信した入力を正しいビジネスプロセスにディスパッチします。これらのフレームワークが「ビュー」と呼ぶものは、実際には少しのすべてです。いくつかのプレゼンテーションロジック(View)、少しの入力処理と検証(Controller)、およびいくつかのビジネスロジック(Model)です。実際のビューのライオンのシェアは、通常「テンプレート」と呼ばれます。
また、多層アーキテクチャについて読むこともできます。ここで、MVCは一方向(フローはコントローラー->モデル->ビュー)であり、多層は双方向(プレゼンテーション->ロジック->データ->ロジック->プレゼンテーション)であり、かなりの数ですMVCを実行するふりをするフレームワークは、実際には3層を実行し、プレゼンテーションをビューに、ロジックをコントローラーに、データをモデルにリラベルします。
ビジネスロジックを完全に分離し、それをプレゼンテーションレイヤーインフラストラクチャから分離するには、アプリケーションサービスによってカプセル化する必要があります。 MVCアーキテクチャはプレゼンテーション層を実装する方法であり、その範囲を維持し、すべてのビジネスロジックをこれらのアプリケーションサービスに委任する必要があります。ビューモデルは、ビューと、表示または読み取りが必要なデータとの間のアダプタと考えてください。コントローラは、ビジネスロジックをホストするビューモデル、ビュー、およびアプリケーションサービス間の相互作用を仲介します。
アプリケーションサービスはビジネスユースケースを実装し、MVCであろうと何かであろうと、プレゼンテーションレイヤーから切り離されます。次に、アプリケーションサービスは トランザクションスクリプト または ドメイン駆動型設計 をホストできます。
ストレージの場合、アプリケーションサービスは repository または永続化メカニズムの任意の抽象化を参照できます。データアクセスをインターフェイスに抽象化することで、さまざまな実装をサポートできます。通常、これらの抽象化は leaky であり、実装間で部分的にのみ移植可能であり、完全な移植性を実現するための無駄な試みであることがよくあります。
[〜#〜]更新[〜#〜]
私の提案は 六角形のアーキテクチャ に基づいています。六角形のアーキテクチャでは、ドメインモデル(ビジネスロジック)がコアです。このコアは、 facade として機能するアプリケーションサービスによってカプセル化されます。アプリケーションサービスは、ドメイン内のユースケースに対応するメソッドを持つ単純なクラスです。アプリケーションサービスの詳細については、 Services in Domain-Driven Design を参照してください。コードサンプルには、購入ドメインのアプリケーションサービスであるPurchaseOrderService
が含まれています。 (アプリケーションサービスはドメイン駆動設計の使用を意味するものではないことに注意してください。)
六角形のアーキテクチャでは、MVCプレゼンテーションレイヤーは、ドメインモデル(ビジネスロジック)とGUIの間のアダプターです。ドメインモデルはプレゼンテーション層を認識していませんが、プレゼンテーション層はドメインモデルを認識しています。
このソリューションには、ビジネスロジックをコントローラーに配置するソリューションよりも確かに可動部分があり、欠点と利点を比較検討する必要があります。私が提案する理由は、複雑さに対処するために、ビジネスロジックをプレゼンテーションレイヤーから切り離しておくことを好むからです。これは、アプリケーションが大きくなるにつれて、より重要になります。
ビジネスロジックの意味によって異なります。モデルの内容に意味を与える「ロジック」は、モデルに含める必要があります。リンクされた質問では、最も投票数の多い回答が「ビジネスロジック」をデータに関連するものとして定義しているようです。これは、ビジネスのデータがビジネスであるという観点からは理にかなっています。
Rails(私は思う)の作成者がモデルに「ビジネスロジック」を入れずに、これについて正確に実行していない例を見たことがある。彼の例は、アプリの登録とログイン-プレーンテキストで提供されたパスワードは、モデル(データベース)に挿入または照会される前に暗号化されました。
コントローラーロジックではなく、モデルに直接属するものの良い例は考えられません。
モデルは無数のデータストアへのインターフェースとなり、移植性の問題を軽減します。モデルインターフェースが実際に「コントローラー」であるかどうかに関係なく、混乱が生じる可能性があります。
一般的に言って、コントローラーはモデルとビューをリンクします(これはアプリのミートとポテトです)。Cocoaの開発では、XCode GUI(コントローラーオブジェクトとバインディング)を介してコントローラーが処理されるまで、単純化することができます。
大まかに引用されたMVCに関するGoFの「設計パターン」セクション:
クラスのMVCトライアドは、Smalltalk-80でユーザーインターフェイスを構築するために使用されます。モデルはアプリケーションオブジェクト、ビューはその画面表示、そしてコントローラーはUIがユーザー入力に反応する方法を定義します。 MVCは、ビューとモデルの間にサブスクライブ/通知プロトコルを確立することにより、ビューとモデルを分離します。次の図は、モデルと3つのビューを示しています。簡略化のため、コントローラーは省略しています。
MVCはすべてUIに関するものです。データの定義と表示-モデルとビューに焦点を当てています。 「サブスクライブ/通知プロトコル」に注意してください-これがコントローラーの出番です。必要なすべてのビューを作成できます。プロトコルに準拠している限り、モデルやコントローラに触れる必要はありません。
特にWeb開発について話している場合、IMHOの多くの一般的なWebフレームワークは、MVCという用語とそのコンポーネント定義により、速くて緩いものです。
サービスレイヤーを導入してみませんか?
そうすれば、コントローラーは無駄がなく読みやすくなり、すべてのコントローラー機能は純粋なアクションになります。
ビジネスロジックは、サービスレイヤー内で必要なだけ分解できます。コードの再利用性が向上し、モデルやリポジトリへの影響はありません。