104

私は、特にファットモデルとスキニーコントローラーアプローチを提唱する多くのブログを読んでいます。Railsキャンプ。その結果、ルーターは基本的に、どのコントローラーでどのメソッドを呼び出すかを把握しているだけであり、コントローラーのメソッドはすべて、モデルの対応するメソッドを呼び出してからビューを表示するだけです。だから私はここで私が理解していない2つの懸念があります:

  1. コントローラーとルーターは、ルートに基づいて神のようなモデルでメソッドを呼び出す以外は、実際にはそれほど異なるタスクを実行していません。
  2. モデルはやりすぎです。メールの送信、関係の作成、他のモデルの削除と変更、タスクのキューイングなど。基本的に、データのモデリングと処理に関係するかどうかに関係なく、すべてを実行することになっている神のようなオブジェクトがあります。

どこに線を引きますか?これはただ神のパターンに陥っているのではありませんか?

4

3 に答える 3

165

RailsをMVCデザインパターンの定番と見なすのは最善の方法ではないかもしれません。このフレームワークは、いくつかの固有の欠点を伴って作成されており(私は別の投稿でそれについて詳しく説明しました)、コミュニティはたった今、フォールアウトに対処し始めています。DataMapper2の開発を最初の主要なステップと見なすことができます。

いくつかの理論

そのアドバイスをする人々は、非常に一般的な誤解に悩まされているようです。それでは、それを明確にすることから始めましょう。最新のMVCデザインパターンでは、モデルはクラスまたはオブジェクトではありません。モデルはレイヤーです。

MVCパターンの背後にある中心的な考え方は関心の分離であり、その最初のステップはプレゼンテーション層とモデル層の間の分割です。プレゼンテーション層がコントローラー(インスタンス、ユーザー入力の処理を担当)、ビュー(インスタンス、UIロジックを担当)、およびテンプレート/レイアウトに分割されるのと同様に、モデル層も同様です。

モデルレイヤーの主な構成要素は次のとおりです。

  • ドメインオブジェクト

    ドメインエンティティ、ビジネスオブジェクト、またはモデルオブジェクトとも呼ばれます(混乱を招くだけなので、後者の名前は嫌いです)。これらの構造は、人々が通常誤って「モデル」と呼ぶものです。彼らはビジネスルール(ドメインロジックの特定のユニットのすべての計算と検証)を含める責任があります。

  • ストレージの抽象化:

    通常、データマッパーパターンを使用して実装されます(この名前を悪用したORMと混同しないでください)。これらのインスタンスは通常、ドメインオブジェクトへの情報の保存(およびドメインオブジェクトへの取得)を担当します。各ドメインオブジェクトは、ストレージのいくつかの形式(DB、キャッシュ、セッション、Cookie、/ dev / null)があるのと同じように、複数のマッパーを持つことができます。

  • サービス:

    アプリケーションロジック(つまり、ドメインオブジェクト間の相互作用およびドメインオブジェクトとストレージ抽象化間の相互作用)を担当する構造。それらは、プレゼンテーション層がモデル層と相互作用するための「インターフェース」のように機能する必要があります。これは通常、Railsのようなコードで最終的にコントローラーに表示されるものです。

これらのグループ間のスペースには、DAO作業単位リポジトリなど、いくつかの構造があります。

ああ...そして(Webのコンテキストで)MVCアプリケーションと対話するユーザーについて話すとき、それは人間ではありません。「ユーザー」は実際にはあなたのウェブブラウザです。

では、神々はどうですか?

恐ろしくてモノリシックなモデルを使用する代わりに、コントローラーはサービスと対話する必要があります。ユーザー入力から特定のサービス(MailServiceまたはRecognitionService)にデータを渡します。このように、コントローラーはモデルレイヤーの状態を変更しますが、これは明確なAPIを使用して行われ、内部構造をいじることはありません(これにより、リークのある抽象化が発生します)。

このような変更は、すぐに反応するか、ビューインスタンスがモデルレイヤーから要求するデータにのみ影響するか、またはその両方に影響する可能性があります。

各サービスは、任意の数のドメインオブジェクトおよびストレージの抽象化と対話できます(ただし、通常はほんの一握りです)。たとえば、RecogitionServiceは記事のストレージの抽象化についてあまり気にすることができませんでした。

クロージングノート

このようにして、任意のレベルで単体テストが可能で、結合が少なく(正しく実装されている場合)、アーキテクチャが明確に理解できるアプリケーションを取得できます。

ただし、覚えておいてください。MVCは小さなアプリケーション向けではありません。MVCパターンを使用してゲストブックページを作成している場合は、間違っています。このパターンは、大規模なアプリケーションで法と秩序を施行するためのものです。

PHPを第一言語として使用している人には、この投稿が関連している可能性があります。これは、いくつかのコードスニペットを含むモデルレイヤーのもう少し長い説明です。

于 2012-12-26T19:53:50.653 に答える
5

「モデル」クラスの実装が不十分な場合は、懸念事項が関係します。モデルクラスはEメール(インフラストラクチャタスク)を実行するべきではありません。

本当の問題は、MVCのモデルが何を意味するのかということです。いくつかのメソッドを持つPOCOクラスに制限されていません。MVCのモデルとは、データとビジネスロジックを意味します。クラシックコアPOCOモデルのスーパーセットとして扱います。

ビュー====コントローラー====モデル--->ビジネスプロセスレイヤー->コアモデル

インフラストラクチャアセンブリとデータアクセスレイヤーを投入し、インジェクションを使用してそれをBPLに渡すと、プロセスは意図したとおりにMVCを使用します。

BPLは、UoW /リポジトリパターンを呼び出し、ビジネスルールを実行し、挿入されたオブジェクトまたはインターフェイスパターンを介してインフラストラクチャ機能を呼び出す場合があります。

したがって、コントローラーをスキニーに保つことを推奨することは、従来のCoreモデルの「person」クラスに50のメソッドがあり、Eメールを直接呼び出す必要があるという意味ではありません。あなたはこれが間違っていると考えるのは正しいです。

コントローラは、直接呼び出された場合でも、インフラストラクチャクラスをインスタンス化してBPLまたはコアレイヤに挿入する必要がある場合があります。ビジネスレイヤー、または少なくともクラシックオブジェクトモデルクラス全体で呼び出しを調整するクラスが必要です。それはとにかく私の「見解」です;-)

MVCの一般的な見解については、wikiの説明http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

MVCの「M」について説明する小さなブログ。http://www.thedeveloperday.com/skinny-controllers/

于 2012-12-26T19:08:24.107 に答える
-1

単一のファットモデル(おそらくアプリまたはアプリケーションという名前)と、論理グループ(ビジネス、顧客、注文、メッセージ)に分類されたいくつかのファットモデルを区別できると思います。後者は私がアプリを構造化する方法であり、各モデルはリレーショナルデータベースのデータベーステーブルまたはドキュメントデータベースのコレクションにほぼ対応しています。これらのモデルは、データベースと通信している場合でもAPIを呼び出している場合でも、モデルを構成するデータの作成、更新、操作のすべての側面を処理します。コントローラは、適切なモデルを呼び出してテンプレートを選択するというほとんどの責任を負いません。

于 2012-12-26T18:54:30.170 に答える