web-dev-qa-db-ja.com

MVCでは、モデルからの基本的なデータ取得をビューで実行できますか?

の細いコントローラー、ファットモデル 'の概念と、出力にデータが必要な場合にビューがモデルを直接呼び出すことができるという一般的な受け入れを考えると、処理を検討する必要がありますコントローラではなくビュー内のリクエストの「取得および表示」部分?例(コードをかなり一般的なものにしようとする):

コントローラ

<?php

class Invoice extends Base_Controller {

    /**
     * Get all the invoices for this month
     */

    public function current_month() {

        // as there's no user input let's keep the controller very skinny,
        // DON'T get data from the Model here, just load the view

        $this->load->view('invoice/current_month');

    }

}

ビュー

<?php

// directly retrieve current month invoices here

$invoices = $this->invoice_model->get_current_month();

// get some other display-only data, e.g. a list of users for a separate list somewhere on the page

$users = $this->user_model->get_users();

?>

<h1>This month's invoices</h1>

<ul>
<?php foreach ($invoices as $invoice) { ?>

<li><?php echo $invoice['ref']; ?></li>

<?php } ?>
</ul>

私にとって、これは、要求が本質的に単なるビューである場合、少なくともある程度は理にかなっています。コントローラーがデータを取得できるのに、コントローラーがデータを収集してビューに渡す必要があるのはなぜですか?これにより、コントローラーは純粋に「アプリケーションレベル」の処理(GET/POSTリクエストの処理、アクセス権とアクセス許可の管理など)のために開いたままになり、モデルの再利用可能性やその他すべての優れた機能を維持します。

この例を拡張して、ユーザーが結果をフィルターできるようにした場合、コントローラーは、フォームからPOSTを処理し、フィルターをビューに渡して、データを再度要求します。フィルターとの時間。

これはMVCアプリケーションを開発する有効な方法ですか?または、コントローラーが果たすべき役割の重要な部分を見落としているか?

10
Adam Westbrook

はい、技術的には可能です。いいえ、それを行うべきではありません。そして、はい、コントローラーの用途が少し不足しています。

コントローラは、ビューをモデルから切り離すためにあります。ビューはほとんど使い捨てのコードと見なす必要があるため、分離は有益です。 UIテクノロジーが変化するにつれて、新しいビューの生成に必要なやり直しを最小限に抑える必要があります。コントローラーはその分離を可能にし、UIテクノロジーを介して存続するコードのための場所を提供します。

モデルを追加または変更する必要がある場合も、逆に機能します。上流の変更はすべてコントローラー内に含まれ、ビューはそのままになります。

その他のリスクは、ビューが非常に単純である一方で、nowであるにもかかわらず、その全体にわたって非常に単純なままである保証は少ないということです。生活。 (非常にシンプルな)ビューから直接モデルを呼び出すことにより、ドアを少し開いて、非常にシンプルなビューをそれほど単純ではないものにする必要がある場合に、後で追加の悪い習慣が忍び込むことを許可します。将来の開発者は、コードをリファクタリングしてコントローラーと対話するのではなく、それほど単純ではないビューからより多くのモデル呼び出しを行うように誘惑されるでしょう。

17
user53019

「細いコントローラー、ファットモデル」の概念と、出力にデータが必要な場合にビューがモデルを直接呼び出すことができるという一般的な受け入れを考えると

いいえ、これは正しくありません。ビューはモデルを直接呼び出すことはできません。プログラマが何らかの理由でそれらのオブジェクトをビューに公開していない限り、ビューはモデルオブジェクトにアクセスできません。

コントローラーではなくビュー内でリクエストの「取得および表示」部分の処理を検討する必要がありますか?

これは基本的にコントローラーを消去し、それらを持っているという意味を打ち負かします。

コントローラーがデータを取得できるのに、コントローラーがデータを収集してビューに渡す必要があるのはなぜですか?

コントローラはデータを収集しません。モデルはデータの収集を行います。 Controller decidesこのデータをビューに渡す必要がある場合。ビューは単にデータの表示を行います。

この例を拡張して、ユーザーが結果をフィルターできるようにした場合、コントローラーは、フォームからPOSTを処理し、フィルターをビューに渡して、データを再度要求します。フィルターとの時間。

番号。

コントローラーは、POSTされたデータが有効かどうかを確認し、このデータをオプションとしてモデルに渡します。モデルはデータソースを照会してデータを返し、コントローラーはそれをビューに渡します。

これはMVCアプリケーションを開発する有効な方法ですか?または、コントローラーが果たすべき役割の重要な部分を見落としているか?

コントローラは、ブラウザからのリクエストに対するハンドラとして動作します。ディスパッチャがリクエストをコントローラーのアクションに送信し、コントローラーのアクションがそのリクエストをモデルに送信します。モデルにはすべてのビジネスロジックが含まれ(これは重要な部分です)、データをコントローラーに返します。その後、コントローラーはデータを簡略化および調整できるため、ビューでの表示が容易になります。

ビューの目的は、HTMLの表示とDataSourceの間の構造と依存関係を分離することです。これは難しいかもしれませんが。ビューは、モデルから直接得られたデータを常に表示するとは限りません。多くの場合、コントローラーは関連する追加データを追加します。

MVCにはたくさんのチュートリアルがあると思います。それらのいくつかを読むことをお勧めします。

6
Reactgular

最近、Pythonを学習しているときに同じ問題に遭遇したため、あなたの質問は非常に興味深いものでした。

与えられた答えは説得力のある議論をしますが、私は、ビューがコントローラーを経由せずにモデルの状態を取得するという出会った別の意見を追加したいと思いました。

MVC

ビューとコントローラーの両方がモデルに依存することに注意することが重要です。ただし、モデルはビューにもコントローラーにも依存しません。これは、分離の主な利点の1つです。この分離により、視覚的な表現とは無関係にモデルを構築およびテストできます。ビューとコントローラーの分離は、多くのリッチクライアントアプリケーションでは二次的なものであり、実際、多くのユーザーインターフェイスフレームワークは役割を1つのオブジェクトとして実装しています。一方、Webアプリケーションでは、ビュー(ブラウザー)とコントローラー(HTTP要求を処理するサーバー側コンポーネント)の分離は非常に明確に定義されています。

モデルビューコントローラーは、ユーザーインターフェイスロジックをビジネスロジックから分離するための基本的な設計パターンです。残念ながら、パターンの人気により、多くの誤った説明が生じています。特に、「コントローラ」という用語は、さまざまな状況でさまざまなことを意味するために使用されてきました。幸いなことに、ビューとコントローラーの分離がはっきりしているため、Webアプリケーションの登場により、いくつかのあいまいさが解消されました。

Smalltalk-80のアプリケーションプログラミング:Model-View-Controller(MVC)[Burbeck92]の使い方で、Steve BurbeckはMVCの2つのバリエーション、パッシブモデルとアクティブモデルについて説明しています。

パッシブモデルは、1つのコントローラーがモデルを排他的に操作するときに使用されます。コントローラーはモデルを変更し、モデルが変更され、更新する必要があることをビューに通知します(図2を参照)。このシナリオのモデルは、ビューとコントローラーから完全に独立しています。つまり、モデルが状態の変化を報告する手段はありません。 HTTPプロトコルはこの例です。ブラウザからサーバーから非同期更新を取得する簡単な方法はありません。ブラウザはビューを表示し、ユーザー入力に応答しますが、サーバー上のデータの変更を検出しません。ユーザーが明示的に更新を要求した場合のみ、サーバーは変更について問い合わせを受けます。

MVC - Passive Model

私はどちらの意見が「正しい」と言う立場にはありません。正直に言うと、ここの回答とリンクされた記事を読んだ後、少し混乱しました。

記事の全文 ここ

3
alnafie

考慮すべきもう1つのことは、ビューがそれらにアクセスできるようにするために_user_model_および_invoice_model_をオートロードしているように見えることです。これが確実に機能するためには、おそらくモデルのallをオートロードします($this->load->model()はビューで正しく表示されないためです...)

これを行うと、決して使用されない可能性のあるものをロードすることにより、スタックを不必要に膨らませます。複数のモデルを用意する理由の1つは、関連するロジックをカプセル化し、特定のタスクに必要なものだけをロードできるようにすることです。

これはCodeIgniterのようです。私は多くのCI開発を行ってきましたが、実際に必要以上に自動ロードしたくないという個人的な経験から共有できます。コントローラーのコンストラクターに$this->output->enable_profiler(TRUE);を追加して、オートロード(databaseなどのヘルパーを含む)をいじってみてください。ロード時間と実行時間に大幅な変化が見られる可能性がありますが特にメモリ割り当て。

1
msanford

簡単に言えば、コードサンプルの形式は一見すると直感的です。これは「心にやさしい」方法だと思われるでしょう。


問題#1

ModelおよびViewオブジェクトは密結合されます。

Modeladdまたはremoveメソッドを使用する必要がある場合は、それに応じてViewを変更する必要があります。

基本的に、MVCはCommandおよびObserverパターンから派生しています。 Controllerがフックできる(つまり、委譲)interface/APIを介して操作されるindependent 'Model'が必要です。

頻繁に、これはinjectingModelおよびViewインスタンスをControllerにインスタンス化し、それらを上記のControllerのプロパティとして格納することを意味します。次に、Controllerのメソッド(つまりコマンド)を作業領域として使用して、-データをaに渡すViewfrom theModel`Modelアプリケーションの状態の更新が終了しました)。

データ(配列、反復可能オブジェクト、その他)を渡すと、ModelViewインスタンスの間でcouplingが保持されますlooseModelインスタンスをViewに挿入する場合は、上記の問題#1を参照してください。

Viewsは、HTML、JSON、テキスト、XML、HTTPヘッダー、YAML、または表現状態転送方法(REST)に準拠したほとんどすべての場合があります

したがって、ModelViewsの関係を管理する方法を理解するための鍵は、それが何であるかについての関係を確認することですone-to-many(潜在的に)!これがまさにObserverパターンが達成するために設計されたものです。

ほとんどの設定では一度に1つのビューしか考慮されませんが、MVCアーキテクチャパターンが一度に複数のビューを更新するのを妨げるものはありません。従来のCRUD Webアプリケーションを使用すると、人々はone-to-oneの方法で考えるようになりますが、これはObserverパターンが機能する最小の例です(one-to-many is theその他)。

したがって、1つのModelと複数のViewsがある場合、_Views'_ API /メソッドで何かを変更したため、すべての_Model's_実装コードを更新する潜在的なheadacheは、次のようになります- 急性

データを渡すViewsないインスタンスModels

0