22

モデルの「ファット」とコントローラーの「スキニー」の概念を理解しようとしています。これまで議論してきたことから、次の例があります(これはfreenodeの議論から取られています):

Q: MVC パラダイムでは、Fat モデル、Skinny Controller と言われています。私がここで考えているのは、CRUD (モデル上) にいくつかの抽象メソッドを使用するメソッド (コントローラー上) がたくさんある場合、モデルの代わりにファット コントローラーを作成しているのでしょうか? または、彼らは、返されて入力されていないものを参照して、太ったモデルと言いますか?それは私が決して理解できなかったことです =) どんなコメントでも大歓迎です! どうもありがとう

OBS1: 私はモデルによって何をしているのではありません。コントローラーでは、モデルに行くものを制御するメソッドを持っているだけです。

OBS2: たとえば、"checkIfEmailExists()" には "john@hotmail.com" がパラメーターとして含まれています。このメソッドは、このパラメーターがテーブルに存在するかどうかを照会するモデル メソッドから戻り値を取得し、ブール値を返します。が 0 の場合、"checkIFemailExists()" は別のモデル メソッドを呼び出します。これは、更新操作を実行する別の抽象メソッドです。

OBS3: 「checkIfEmailExists()」は単なるコントローラーではありませんか? 彼は実際にはCRUDを実行していません。値などを比較しているだけです。私の頭の中ではこれはコントローラーなので、それが私を混乱させます:S

注: これは最良の例ではないと思います。「何かが存在するかどうかを確認してください」と言うと、テーブル操作のクエリのように聞こえるからです。

Q2: もう 1 つ質問があります。たとえば、メール アドレス パラメータの送信元であるビュー フォームがあるとします。ビューがモデルに直接行くと言っていますか?

Q3:コントローラはそれらの間で動作するべきではありませんか? それがパラダイムです

最終注記: 議論は、私が間違っていると言って終了しました。希望は大丈夫です (私は学んでいます)。Q2とQ3の正解は?

ご清聴ありがとうございました

4

5 に答える 5

34

アプリケーションは M です。V および C から独立して立つことができる必要があります。V および C は、アプリケーションへのユーザー インターフェイスを形成します。これが Web インターフェースであるかコマンド ライン インターフェースであるかは、アプリケーションのコア ビジネス ロジックを実行する上で重要ではありません。モデルをビジネス ロジックで太らせたい。

代わりに、たとえばビジネスロジックでいっぱいのファットコントローラーを使用している場合、MVC の目的を順守していません。コントローラーの唯一の責任は、モデルへの UI 要求の処理と委任です。だからこそ痩せるべきです。責任を負うものに必要なコードのみを含める必要があります。

簡単な例

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $bar = Sanitizer::sanitize($_POST['bar']);
        $rows = $this->database->query('SELECT * from table');
        try {
            foreach($rows as $row) {
                $row->foo = $bar;
                $row->save();
            }
        } catch (Exception $e) {
            $this->render('errorPage');
            exit;
        }
        $this->render('successPage');
    } else {
        $this->render('fooPage');
    }
}

あるべきとき

public function fooAction()
{
    if(isset($_POST['bar'])) {
        $success = $this->tableGateway->updateFoo($_GET['bar']);
        $page    = $success ? 'successPage' : 'errorPage';
        $this->render($page);
    } else {
        $this->render('fooPage');
    }
}

コントローラーが知る必要があるのはそれだけだからです。行を更新しないでください。誰かがこの変更を要求したことをモデルに伝えるだけです。更新は、行を管理するクラスの責任です。また、コントローラーは必ずしも値をサニタイズする必要はありません。

Q2 と Q3 については、 Can I call a Model from the Viewに対する私の回答を参照してください。

于 2010-06-24T12:27:10.173 に答える
9

私は長い間 MVC パラダイムを扱ってきましたが、私の経験を皆さんと共有できます。

「モデル」部分は、検証、ロジック、データ アクセスなど、厳密には「Web」ではないすべてのものを処理する責任があります。これは一種の混合ビジネス レイヤー + データ アクセス レイヤーと考えてください。また、BLL+DAL を個別のアセンブリに配置し、MVC の "モデル" 部分を BLL とアプリの間のブリッジとして使用することもできます。また、ViewData クラスなど、MVC アプリに固有で BLL に関連しないクラスを追加することもできます。など

「コントローラー」部分は、認証、Cookie、GET と POST、クエリ文字列などの Web 固有のものを処理するものです。モデルや BLL に存在するものを使用し、レンダリングする必要があるデータを送信します。ユーザーにビューに。

「ビュー」は、コントローラーからデータを受信して​​表示できる HTML テンプレートです。ビューで論理演算を実行してはならないため、「if」ステートメントやループなどはありません。そのようなニーズがある場合は、目的の html を作成してからそれらを呼び出す「ヘルパー」メソッドが必要です。見る。したがって、ビューはデータを受け取るだけで、データをコントローラーに投稿するためのリンク/フォームをユーザーに提供しますが、何も詳しく説明しません。

これで疑問が解消されることを願っています。

于 2010-06-24T12:11:58.300 に答える
3

私はいつもこれを、より手続き的なアプローチですべてのロジックをコントローラーに持つのではなく、よりオブジェクト指向のアプローチでモデルがそれらのモデルに関連するロジックをカプセル化する必要があることを意味すると解釈してきました。大聖堂とバザールを引用するには:

スマートなデータ構造と愚かなコードは、その逆よりもはるかにうまく機能します。

于 2010-06-24T12:16:40.443 に答える
2

私は (C# に対して) 偏見を示しているかもしれませんが、オブジェクト指向プログラミング スタイルを使用していない限り、MVC について話すことはあまり意味がないと思います。コントローラーはメソッドではなく、クラスにグループ化されたメソッドのコレクションであり、それぞれがいくつかの入力 (url/request) を処理します。モデルはデータベースにアクセスする方法 (データ アクセス レイヤー) ではなく、アプリケーション内の識別可能なエンティティ (人、予約、製品など) をカプセル化するプロパティとメソッドのコレクションです。コントローラーが入力を処理し、モデルにデータが含まれていることを考えてみてください。もちろん、それは単純化されています。

私にとって、「ファット」と「スキニー」の問題は、ビジネス ロジックがどこにあるのかという問題です。単に入力を処理するのではなく、ビジネスロジックを実装することに関連するコントローラーに多くのロジックがある場合、コントローラーは、レンダリングするためにビューに渡されるモデルの集合体にリクエストを変換するためにそれらを使用する場合よりも比較的太くなります。 . 私の経験では、常にどちらかまたは両方の決定であるとは限りません。多くの場合、モデルにはビジネス ロジック (検証、関係維持、監査) があり、コントローラーにはアプリケーション ロジック (アクセス許可の検証、サニタイズなど) もあります。

于 2010-06-24T12:20:23.493 に答える
0

コントローラーとモデルの適切な分離は、コントローラーに「構文」に依存する操作を実行させ、ビジネスロジックをまったく/ほとんど含まず、モデルを使用して「セマンティック」関連の操作を実行させることで実現できると思います。

その分離の良い例は次のとおりです。

コントローラーで電子メールの正規表現チェックを実行できますが、コントローラーでその電子メールの LDAP マッチングを実行しません。

于 2010-06-24T12:17:28.587 に答える