35

MVC のビューの概念を理解するのに問題があるように思われます。私が読んだことによると、それらはアプリケーションでプレゼンテーションを管理するレイヤーですが、私が読んだ資料の多くはこれに関して異なるようですPHP Master.comからのこの問題。

View は HTML コードを返す関数を持つクラスですが、残りの HTML はどこにあるのでしょうか? この View コードにアクセスする独立した .html ページに配置する必要がありますか?

この記事では、php-html.netのビューは拡張子が .php の単純な HTML ファイルですが、そのデータにどのようにアクセスしているのでしょうか? require()最初のチュートリアルのインスタンス化のようなものは見当たりません。

4

7 に答える 7

81

注: MVC および MVC にインスパイアされたパターンは高度な構造です。これらは、通常のオブジェクト指向 ( SOLIDおよびその他のガイドラインに従う) コードが管理不能になり始めるコードベースで使用されることを意図しています。このパターンを導入すると、追加の制約が課され、非常に複雑なアプリケーションを含めることができます。MVC は、"hello world" アプリ向けではありません。


最初から始めましょう...

MVC および MVC にインスパイアされたデザイン パターンの背後にあるコア アイデアは、関心の分離です。上記の分離は 2 重です。

  • モデル レイヤーは UI レイヤーとは別のものです。
  • ビューはコントローラーから分離されています

ここに画像の説明を入力

モデル層(「クラス」や「オブジェクト」ではない) には、いくつかの構造グループが含まれ、それぞれがビジネス ロジックの異なる側面として扱われます。主な部分は次のとおりです。

  • ドメイン オブジェクト: 検証、ビジネス ルール
  • ストレージの抽象化: ドメイン オブジェクトからのデータの永続化とキャッシュ
  • サービス: アプリケーション ロジック

また、リポジトリ作業単位などが混在している可能性があります。

UI レイヤーは、主にビューとコントローラーで構成されます。ただし、どちらもサービスを利用してモデル層とやり取りします。サービスは、コントローラーがモデル レイヤーの状態を変更し、ビューがその新しい状態に基づいて情報を収集する方法を提供します。

Web のコンテキストでは、Web アプリケーションが示す要求と応答の性質のために、ビューとコントローラーは緩いペアを形成します。

コントローラーは現在のビューの状態を直接変更できますが、これらの変更はモデルを通じて行われることがより一般的であることに注意してください。ビューを直接変更する理由の 1 つは、たとえば、XML の代わりに JSON で応答する必要がある場合です。

また、出力形式ごとに異なるビューを簡単にインスタンス化し、ポリモーフィズムを利用できると主張することもできます。


ビューではないものは何ですか?

ビューは単に美化されたテンプレート ファイルであるという誤解が広まっています。この間違いは、RubyOnRails プロトタイピング フレームワークのリリース後に非常に一般的になりました。

ビューはテンプレートではありません。それらをそのまま使用すると、MVC および MVC にインスパイアされたパターンの背後にあるコア原則を破ることになります。

テンプレートがビューであると仮定すると、アーキテクチャに大きな影響を与えます。ビューにはプレゼンテーション ロジックを配置する場所がないため、コントローラーまたはモデル レイヤーのいずれかにプレゼンテーション ロジックをプッシュします。ほとんどの人は、プレゼンテーション ロジックがモデル レイヤーに存在しないことを理解しているため、通常は "コントローラー" を選択します。

基本的に、これによりビューとコントローラーがマージされます。


ビューは何をしていますか?

ビューの役割は、プレゼンテーション ロジックを処理することです。Web のコンテキストでは、ビューの目標はユーザーへの応答を生成することです(ちなみに、これは人間ではなくブラウザーです)

技術的には、ユーザー Web ソケットがモデル層を監視するクライアント側のビューを作成することは可能ですが、実際には実装することは事実上不可能です。特にPHP環境ではありません。

この応答ビューを作成するには、モデル層から情報を取得し、収集されたデータに基づいて、データをテンプレートに配布してレンダリングするか、場合によっては単純に HTTP ロケーション ヘッダーを送信することによって、応答を組み立てます。

Post/Redirect/Getを使用する場合、リダイレクト部分は、よくあるコントローラーではなく、ビューによって実行されます。


非常に主観的なビット:

最近、次のアプローチを使用して MVC と対話することを好みました。

  // the factory for services was injected in constructors
  $controller->{ $method.$command }($request);
  $response = $view->{ $command }();
  $response->send();

$method現在のREQUEST_METHODであり、REST のような API を装うように調整されており、$command人々が通常「アクション」と呼ぶものです。GETコントローラーには、とPOST(別の) 要求用の別個のルーチンがあります。ifこれは、すべての「アクション」で同じものを避けるのに役立ちます。

ビューでは、同様の名前のメソッドを呼び出して、クライアントに送信される応答を準備します。

警告: このセットアップにはSRP違反が含まれていると思われます。それを自分のものとして採用するのは悪い考えかもしれません。


DRYはどうですか?

既にお気付きかもしれませんが、ビューをインスタンスとして持つことには若干の問題があります。コードの断片が繰り返されることになります。例: メニューまたはページネーション。

ページネーションを見てみましょう.. ページネーションにはロジックが含まれていますが、このロジックはモデルレイヤーとは関係ありません。モデルには「ページ」という概念がありません。代わりに、このビットのロジックは UI レイヤーに常駐します。しかし、各ビューにページネーションが含まれているか継承されている場合、それは明らかに SRP (および実際には他のいくつかの原則) に違反しています。

この問題を回避するために、ビューにプレゼンテーション オブジェクトを導入することができます (そしてそうすべきです)。

注: Fowler はそれらを「プレゼンテーション モデル」と呼んでいますが、私はその名前が「モデルとは何か」という全体的な混乱を助長していると思います。したがって、代わりに「プレゼンテーション オブジェクト」と呼ぶことをお勧めします。

プレゼンテーション オブジェクトは、繰り返されるロジックを処理します。これにより、ビューがはるかに「軽く」なり、一部の側面では、モデル層からのサービスの構造を反映し始めます。

プレゼンテーション オブジェクトとテンプレート間の相互作用は、ドメイン オブジェクトとデータ マッパー間の相互作用に似ています。


このすべてが常に必要ですか?

いいえ。この特定のアプローチは、UI レイヤーが非常に複雑なコードを対象としており、入力の処理をプレゼンテーションから分離する必要があります。

アプリケーションが .. emm .. のような非常にシンプルな UI を持っている場合、より大きな統合プロジェクト用の REST API を作成しています。そのような実用的なオプションは、すべてのコントローラーとビューのペアを単一のクラスにマージすることです。

また、従来のコードベースをリファクタリングする場合にも、この制約の少ないアプローチにより古いコードのチャンク全体を移動できるため、良いステップになる可能性があります。そのような古いコードの断片を分離し、すべてがまだ機能することを確認したら (レガシー コードにはテストがないため、それが「レガシー」になる方法です)、ビジネス ロジックの分離に集中しながら、さらに分割を開始できます。 UIから。


PS私自身は、ビューを処理する最善の方法を見つけるのにまだ苦労しています。この投稿は答えではなく、私の現在の理解のスナップショットのようなものです。

于 2013-05-16T20:18:44.657 に答える
1

出力形式に関係なく、ビューを構築するために必要なすべてのメソッドをビュー クラスに渡す必要があります。ほとんどの開発者は、何らかのテンプレート エンジンを使用してページの大部分を構築し、リクエスト固有の情報を本文に入力します。これを行う方法はたくさんあります。フォームや入力などの一般的な要素のヘルパー メソッドを定義する抽象ビュー クラスを用意することもお勧めします。

このレイヤーは抽象化されているため、デザインや出力形式を何らかの方法で変更する場合でも、アプリケーションのロジックを変更する必要はありません。

編集: MVC セットによって表される各モジュールには、出力をブラウザーに送信するメソッドのコレクションを持つ独自のビューがあります。さまざまな方法がありますが、一例を次に示します。

class testModule_view extends viewAbstract {
    public function showTestData($title, $subtitle, $data) {
        $XHTML = '<h1>' . $title . '</h1>'
            . '<h2>' . $subtitle . '</h2>'
            . parent::data2table($data);

        parent::outputToBrowser(DEFAULT_TEMPLATE, $XHTML);
    }
}

これは、単純なビュー メソッドがどのようなものかを示す簡単な例です。

于 2013-05-16T18:38:25.917 に答える
1

異なるフレームワークは、異なるロジックを使用して変数を割り当て、そのコンテンツを表示および取得します。以下は、ob_start() 関数を使用した簡単な例です。

<?php
     $title = 'Hello...';
     ob_start();
     file_get_contents('view.phtml');
     $viewContents = ob_get_clean();
     echo $viewContents;

?>

//view.phtml
<b>Hello the title is <?php echo $title; ?></b>

これがあなたの質問に答えてくれることを願っています...

于 2013-05-16T18:51:37.073 に答える
0

ブラウザーがページを呼び出すと、このページのコントローラーが読み込まれます。コントローラーはアプリのライフサイクルを管理します。彼は、データを取得するためだけに使用されるモデルからデータを取得します (おそらくデータベースから)。ビューは HTML のみであり、コントローラーはビューをエコーし​​、必要に応じていくつかのパラメーターを渡します。

于 2013-05-16T18:39:18.450 に答える